<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link href="common/css/sf.css" rel="stylesheet" type="text/css"/>
<title>Smallstep: 小步操作语义</title>
</head>
<link href="common/jquery-ui/jquery-ui.css" rel="stylesheet">
<script src="common/jquery-ui/external/jquery/jquery.js"></script>
<script src="common/jquery-ui/jquery-ui.js"></script>
<script src="common/toggleproofs.js"></script>
<link href="common/css/plf.css" rel="stylesheet" type="text/css"/>

<body>

<div id="page">

<div id="header">
<a href='https://coq-zh.github.io/SF-zh/index.html'>
<img src='common/media/image/sf_logo_sm.png'></a>
</br><a href='index.html'>  <span class='booktitleinheader'>Volume 2: 编程语言基础</span><br></br>
<ul id='menu'>
   <a href='toc.html'><li class='section_name'>目录</li></a>
   <a href='coqindex.html'><li class='section_name'>索引</li></a>
   <a href='deps.html'><li class='section_name'>路线</li></a>
</ul>
</a></div>

<div id="main">

<h1 class="libtitle">Smallstep<span class="subtitle">小步操作语义</span></h1>


<div class="code code-tight">

<span class="id" type="keyword">Set</span> <span class="id" type="var">Warnings</span> "-notation-overridden,-parsing".<br/>
<span class="id" type="var">From</span> <span class="id" type="var">Coq</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">Arith.Arith</span>.<br/>
<span class="id" type="var">From</span> <span class="id" type="var">Coq</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">Arith.EqNat</span>.<br/>
<span class="id" type="var">From</span> <span class="id" type="var">Coq</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">Init.Nat</span>.<br/>
<span class="id" type="var">From</span> <span class="id" type="var">Coq</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">omega.Omega</span>.<br/>
<span class="id" type="var">From</span> <span class="id" type="var">Coq</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">Lists.List</span>.<br/>
<span class="id" type="keyword">Import</span> <span class="id" type="var">ListNotations</span>.<br/>
<span class="id" type="var">From</span> <span class="id" type="var">PLF</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">Maps</span>.<br/>
<span class="id" type="var">From</span> <span class="id" type="var">PLF</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">Imp</span>.<br/>
</div>

<div class="doc">
我们目前见到的（对 <span class="inlinecode"><span class="id" type="var">aexp</span></span>，<span class="inlinecode"><span class="id" type="var">bexp</span></span> 和命令的）求值器是以“大步（big-step）”
    风格构造的：它们以“单一大步（one big-step）”的方式描述了一个表达式如
    何被求值到最终值上（或一个命令及存储被求值到最终存储上）。

<div class="paragraph"> </div>

    对许多目的而言，这种风格非常简单和自然——确实，它的普及者 Gilles Kahn 也把它
    叫做<b>自然语义（natural semantics）</b>。但仍然有一些它不擅长的事情。
    特别是，它并没有提供一种自然的方式来描述<b>并发（concurrent）</b>程序语言，
    其语义——即，程序如何运行的本质——不仅仅关于输入状态如何被映射到输出状态，
    还包括经过的中间状态，因为当代码并发执行时这些中间状态同样可以被观察到。

<div class="paragraph"> </div>

    大步语义风格的另一个缺点更加技术性，但在一些情况下却非常重要。假设我们定义了一个
    Imp 的变种，语言的变量是数字<b>或</b>数字的列表。这个扩展语言的语法允许我们写下例如
    <span class="inlinecode">2</span> <span class="inlinecode">+</span> <span class="inlinecode"><span class="id" type="var">nil</span></span> 这样的奇怪表达式，而算数表达式的语义则必须描述这样的表达式是如何执行的。
    一种方式是把列表也视作数字，并延续每个表达式都被求值到数字上的约定——比如，当上下文
    需要一个数字时，列表会被解释为 <span class="inlinecode">0</span>。但这样做其实有一点敷衍了事。

<div class="paragraph"> </div>

    另一种更加自然的方式是说像 <span class="inlinecode">2+<span class="id" type="var">nil</span></span> 这类表达式的行为是<b>未定义的（undefined）</b>
    ——即，它根本不会被求值到任何结果。我们可以简单地达到这个目的：只需要把 <span class="inlinecode"><span class="id" type="var">aeval</span></span>
    和 <span class="inlinecode"><span class="id" type="var">beval</span></span> 以 <span class="inlinecode"><span class="id" type="keyword">Inductive</span></span> 命题而非 <span class="inlinecode"><span class="id" type="var">Fixpoints</span></span> 的方式来编写，这样我们便可
    以表达偏函数而非全函数。

<div class="paragraph"> </div>

    然而，现在我们遇到了一个更严重地问题。在这个语言中，有<b>两种非常不同的原因</b>导致
    一个命令无法把初始状态映射到任何地结束状态：执行进入了无限循环；或者在某个点，程序
    尝试进行一个无意义的操作，比如对一个数字和列表求和，由此无法应用任何一个求值规则。

<div class="paragraph"> </div>

    这两种结果——非停机状态 vs. 在错误的结构上卡住（stuck）——不应当被混淆。特别地，我们想要
    以添加某种形式的<b>类型检查（typechecking）</b>的方式来<b>允许</b>第一种情况（这是我们为
    了方便地使用像 <span class="inlinecode"><span class="id" type="var">while</span></span> 这类通用循环构造所付出的必要代价），但<b>阻止</b>第二种情况
    （也即错误的程序）。在剩下的课程中，这会是我们主要讨论的话题。作为第一步，我们需要一种
    语义来区分非停机状态和错误的“卡住状态（stuck states）”。

<div class="paragraph"> </div>

    因此，出于这些原因，我们希望有一种更精细化的方式来定义和推理程序的行为。这便是本章的话题。
    我们的目的是用“小步（small-step）”关系来代替“大步（big-step）”的 <span class="inlinecode"><span class="id" type="var">eval</span></span> 关系，
    前者对于给定的程序，描述了计算是如何以“不可分步骤（atomic steps）”执行的。 
</div>

<div class="doc">
<a name="lab134"></a><h1 class="section">一个玩具语言</h1>

<div class="paragraph"> </div>

 为了简化讨论，让我们回过头来考虑一个只含有常量和加法的简单语言。
    （我们使用字母——<span class="inlinecode"><span class="id" type="var">C</span></span> 和 <span class="inlinecode"><span class="id" type="var">P</span></span>（代表常量（Constant）和加法（Plus）——
    简洁地作为构造子的名字。）在本章的最后，我们回看到如何将这些技术应用到
    Imp 语言上。
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">tm</span> : <span class="id" type="keyword">Type</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">C</span> : <span class="id" type="var">nat</span> → <span class="id" type="var">tm</span>         <span class="comment">(*&nbsp;常量&nbsp;*)</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">P</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span>. <span class="comment">(*&nbsp;加法&nbsp;*)</span><br/>
</div>

<div class="doc">
这是我们之前学习的大步语义风格求值器。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Fixpoint</span> <span class="id" type="var">evalF</span> (<span class="id" type="var">t</span> : <span class="id" type="var">tm</span>) : <span class="id" type="var">nat</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">t</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">C</span> <span class="id" type="var">n</span> ⇒ <span class="id" type="var">n</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">P</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span> ⇒ <span class="id" type="var">evalF</span> <span class="id" type="var">a<sub>1</sub></span> + <span class="id" type="var">evalF</span> <span class="id" type="var">a<sub>2</sub></span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
这是用同样风格描述的等价求值器，只是用归纳关系来定义。
    我们使用记号 <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode">==&gt;</span> <span class="inlinecode"><span class="id" type="var">n</span></span> 来表达“<span class="inlinecode"><span class="id" type="var">t</span></span> 求值到 <span class="inlinecode"><span class="id" type="var">n</span></span>”。 
<div class="paragraph"> </div>

<center><table class="infrule">
<tr class="infruleassumption">
  <td class="infrule">&nbsp;&nbsp;</td>
  <td class="infrulenamecol" rowspan="3">
    (E_Const) &nbsp;
  </td></tr>
<tr class="infrulemiddle">
  <td class="infrule"><hr /></td>
</tr>
<tr class="infruleassumption">
  <td class="infrule">C&nbsp;n&nbsp;==>&nbsp;n</td>
  <td></td>
</td>
</table></center><center><table class="infrule">
<tr class="infruleassumption">
  <td class="infrule">t<sub>1</sub>&nbsp;==>&nbsp;n<sub>1</sub></td>
  <td></td>
</td>
<tr class="infruleassumption">
  <td class="infrule">t<sub>2</sub>&nbsp;==>&nbsp;n<sub>2</sub></td>
  <td class="infrulenamecol" rowspan="3">
    (E_Plus) &nbsp;
  </td></tr>
<tr class="infrulemiddle">
  <td class="infrule"><hr /></td>
</tr>
<tr class="infruleassumption">
  <td class="infrule">P&nbsp;t<sub>1</sub>&nbsp;t<sub>2</sub>&nbsp;==>&nbsp;n<sub>1</sub>&nbsp;+&nbsp;n<sub>2</sub></td>
  <td></td>
</td>
</table></center>
</div>
<div class="code code-tight">

<span class="id" type="keyword">Reserved Notation</span> " t '==&gt;' n " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 50, <span class="id" type="var">left</span> <span class="id" type="var">associativity</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">eval</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">nat</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">E_Const</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">C</span> <span class="id" type="var">n</span> ==&gt; <span class="id" type="var">n</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">E_Plus</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> ==&gt; <span class="id" type="var">n<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>2</sub></span> ==&gt; <span class="id" type="var">n<sub>2</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> ==&gt; (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)<br/>
<span class="id" type="keyword">where</span> " t '==&gt;' n " := (<span class="id" type="var">eval</span> <span class="id" type="var">t</span> <span class="id" type="var">n</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Module</span> <span class="id" type="var">SimpleArith1</span>.<br/>
</div>

<div class="doc">
现在，我们展示对应的<b>小步</b>求值关系。  <center><table class="infrule">
<tr class="infruleassumption">
  <td class="infrule">&nbsp;&nbsp;</td>
  <td class="infrulenamecol" rowspan="3">
    (ST_PlusConstConst) &nbsp;
  </td></tr>
<tr class="infrulemiddle">
  <td class="infrule"><hr /></td>
</tr>
<tr class="infruleassumption">
  <td class="infrule">P&nbsp;(C&nbsp;n<sub>1</sub>)&nbsp;(C&nbsp;n<sub>2</sub>)&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;C&nbsp;(n<sub>1</sub>&nbsp;+&nbsp;n<sub>2</sub>)</td>
  <td></td>
</td>
</table></center><center><table class="infrule">
<tr class="infruleassumption">
  <td class="infrule">t<sub>1</sub>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;t<sub>1</sub>'</td>
  <td class="infrulenamecol" rowspan="3">
    (ST_Plus1) &nbsp;
  </td></tr>
<tr class="infrulemiddle">
  <td class="infrule"><hr /></td>
</tr>
<tr class="infruleassumption">
  <td class="infrule">P&nbsp;t<sub>1</sub>&nbsp;t<sub>2</sub>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;P&nbsp;t<sub>1</sub>'&nbsp;t<sub>2</sub></td>
  <td></td>
</td>
</table></center><center><table class="infrule">
<tr class="infruleassumption">
  <td class="infrule">t<sub>2</sub>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;t<sub>2</sub>'</td>
  <td class="infrulenamecol" rowspan="3">
    (ST_Plus2) &nbsp;
  </td></tr>
<tr class="infrulemiddle">
  <td class="infrule"><hr /></td>
</tr>
<tr class="infruleassumption">
  <td class="infrule">P&nbsp;(C&nbsp;n<sub>1</sub>)&nbsp;t<sub>2</sub>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;P&nbsp;(C&nbsp;n<sub>1</sub>)&nbsp;t<sub>2</sub>'</td>
  <td></td>
</td>
</table></center>
</div>
<div class="code code-tight">

<span class="id" type="keyword">Reserved Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">step</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_PlusConstConst</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>2</sub></span>) <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">C</span> (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">t<sub>2</sub>'</span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " := (<span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/>
</div>

<div class="doc">
值得注意的几点：

<div class="paragraph"> </div>

<ul class="doclist">
<li> 我们定义的仅仅是单步关系，其中只有一个 <span class="inlinecode"><span class="id" type="var">P</span></span> 节点被其值替换。

<div class="paragraph"> </div>


</li>
<li> 每步找到准备好的<b>最左侧（leftmost）</b> <span class="inlinecode"><span class="id" type="var">P</span></span> 节点（也即其操作数都是常量），
      并在原地重写它。第一个规则是说如何重写 <span class="inlinecode"><span class="id" type="var">P</span></span> 节点自己；剩下的两个是说如何
      得到这样的 <span class="inlinecode"><span class="id" type="var">P</span></span>。

<div class="paragraph"> </div>


</li>
<li> 一个常量项无法继续被求值。 
</li>
</ul>

<div class="paragraph"> </div>

 让我们暂停一下，并使用 <span class="inlinecode"><span class="id" type="var">step</span></span> 关系来推理一些例子…… 
<div class="paragraph"> </div>

 如果 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 可向前一步到 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub>'</span></span>，那么 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 可向前一步到 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub>'</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span>: 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Example</span> <span class="id" type="var">test_step_1</span> :<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 0) (<span class="id" type="var">C</span> 3))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 2) (<span class="id" type="var">C</span> 4))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> (0 + 3))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 2) (<span class="id" type="var">C</span> 4)).<br/>
<div class="togglescript" id="proofcontrol1" onclick="toggleDisplay('proof1');toggleDisplay('proofcontrol1')"><span class="show"></span></div>
<div class="proofscript" id="proof1" onclick="toggleDisplay('proof1');toggleDisplay('proofcontrol1')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>. <span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
<a name="lab135"></a><h4 class="section">练习：1 星, standard (test_step_2)</h4>
 当求和操作的左侧表达式已经完成求值，其右侧表达式可向前一步：
    如果 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 可向前一步到 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub>'</span></span>，那么 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode">(<span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n</span>)</span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 可向前一步到 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode">(<span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n</span>)</span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub>'</span></span>： 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Example</span> <span class="id" type="var">test_step_2</span> :<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> 0)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> 2)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 0) (<span class="id" type="var">C</span> 3)))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> 0)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> 2)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> (0 + 3))).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="code code-tight">

<span class="id" type="keyword">End</span> <span class="id" type="var">SimpleArith1</span>.<br/>
</div>

<div class="doc">
<a name="lab136"></a><h1 class="section">关系</h1>

<div class="paragraph"> </div>

 我们将会研究多个不同的单步关系，因此泛化一下这个概念，给出一些关系的一般定义和
    定理是十分有帮助的。（可选章 <span class="inlinecode"><span class="id" type="var">Rel.v</span></span> 以更细致的方式开发了这个想法；放在这里
    可能会对读者有帮助，但内容过于密集。）

<div class="paragraph"> </div>

    集合 <span class="inlinecode"><span class="id" type="var">X</span></span> 上的<b>二元关系（binary relation）</b>是由 <span class="inlinecode"><span class="id" type="var">X</span></span> 中的两个元素参数化的
    命题——也即，一个 <span class="inlinecode"><span class="id" type="var">X</span></span> 上序对的命题。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">relation</span> (<span class="id" type="var">X</span> : <span class="id" type="keyword">Type</span>) := <span class="id" type="var">X</span> → <span class="id" type="var">X</span> → <span class="id" type="keyword">Prop</span>.<br/>
</div>

<div class="doc">
本章中，我们主要的例子将会是单步规约关系，<span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span>，以及它的多步版本，
    <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span>（后面会定义），但是也有许多其他例子——比如，“等于”、“小于”、“小于等于”
    和数字上“平方数”关系，还有字符串和列表的“前缀”关系。
<div class="paragraph"> </div>

 和 Imp 的大步求值关系一样，<span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span> 关系的一个简单性质是<b>确定性（deterministic）</b>。

<div class="paragraph"> </div>

    <b>定理</b>：对于每个 <span class="inlinecode"><span class="id" type="var">t</span></span>，最多有一个 <span class="inlinecode"><span class="id" type="var">t'</span></span> 且 <span class="inlinecode"><span class="id" type="var">t</span></span> 向前一步到 <span class="inlinecode"><span class="id" type="var">t'</span></span>
     (<span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span> <span class="inlinecode"><span class="id" type="var">t'</span></span> 是可证的)。这也就是说 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span> 是确定性的。
<div class="paragraph"> </div>

 <b>证明草稿</b>：我们通过对 <span class="inlinecode"><span class="id" type="var">step</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">y<sub>1</sub></span></span> 的导出式（derivation）进行归
    纳来证明如果 <span class="inlinecode"><span class="id" type="var">x</span></span> 同时前进到 <span class="inlinecode"><span class="id" type="var">y<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">y<sub>2</sub></span></span>，那么 <span class="inlinecode"><span class="id" type="var">y<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">y<sub>2</sub></span></span> 是相等的。
    取决于导出式中最后使用的规则和 <span class="inlinecode"><span class="id" type="var">step</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">y<sub>2</sub></span></span> 的导出式中最后的规则，我们有许多
    情形需要考虑。

<div class="paragraph"> </div>

<ul class="doclist">
<li> 如果二者皆为 <span class="inlinecode"><span class="id" type="var">ST_PlusConstConst</span></span>，那么结果是显然的。

<div class="paragraph"> </div>


</li>
<li> 对于两个导出式都以 <span class="inlinecode"><span class="id" type="var">ST_Plus1</span></span> 或 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span> 结束的情形，可直接从归纳假设中得证。

<div class="paragraph"> </div>


</li>
<li> 其中一个是 <span class="inlinecode"><span class="id" type="var">ST_PlusConstConst</span></span> 同时另一个是 <span class="inlinecode"><span class="id" type="var">ST_Plus1</span></span> 或 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span>
        的情形是不可能发生的，因为这蕴含了 <span class="inlinecode"><span class="id" type="var">x</span></span> 形如 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 而 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span>
        都是常量（根据 <span class="inlinecode"><span class="id" type="var">ST_PlusConstConst</span></span>）<b>且</b> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 或 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 中的一个形如
        <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">_</span></span>。

<div class="paragraph"> </div>


</li>
<li> 类似地，一个是 <span class="inlinecode"><span class="id" type="var">ST_Plus1</span></span> 同时另一个是 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span> 的情形也不可能发生，
        因为这蕴含了 <span class="inlinecode"><span class="id" type="var">x</span></span> 形如 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 而 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 同时是 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>11</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>12</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n</span></span>
        两种形式。 <span class="proofbox">&#9744;</span>  
</li>
</ul>

<div class="paragraph"> </div>

 形式化地来说： 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">deterministic</span> {<span class="id" type="var">X</span> : <span class="id" type="keyword">Type</span>} (<span class="id" type="var">R</span> : <span class="id" type="var">relation</span> <span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">x</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">y<sub>2</sub></span> : <span class="id" type="var">X</span>, <span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">y<sub>1</sub></span> → <span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">y<sub>2</sub></span> → <span class="id" type="var">y<sub>1</sub></span> = <span class="id" type="var">y<sub>2</sub></span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Module</span> <span class="id" type="var">SimpleArith2</span>.<br/>
<span class="id" type="keyword">Import</span> <span class="id" type="var">SimpleArith1</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">step_deterministic</span>:<br/>
&nbsp;&nbsp;<span class="id" type="var">deterministic</span> <span class="id" type="var">step</span>.<br/>
<div class="togglescript" id="proofcontrol2" onclick="toggleDisplay('proof2');toggleDisplay('proofcontrol2')"><span class="show"></span></div>
<div class="proofscript" id="proof2" onclick="toggleDisplay('proof2');toggleDisplay('proofcontrol2')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">deterministic</span>. <span class="id" type="tactic">intros</span> <span class="id" type="var">x</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">y<sub>2</sub></span> <span class="id" type="var">Hy<sub>1</sub></span> <span class="id" type="var">Hy<sub>2</sub></span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="tactic">dependent</span> <span class="id" type="var">y<sub>2</sub></span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">induction</span> <span class="id" type="var">Hy<sub>1</sub></span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">y<sub>2</sub></span> <span class="id" type="var">Hy<sub>2</sub></span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;ST_PlusConstConst&nbsp;*)</span> <span class="id" type="tactic">inversion</span> <span class="id" type="var">Hy<sub>2</sub></span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_PlusConstConst&nbsp;*)</span> <span class="id" type="tactic">reflexivity</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_Plus1&nbsp;*)</span> <span class="id" type="tactic">inversion</span> <span class="id" type="var">H<sub>2</sub></span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_Plus2&nbsp;*)</span> <span class="id" type="tactic">inversion</span> <span class="id" type="var">H<sub>2</sub></span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;ST_Plus1&nbsp;*)</span> <span class="id" type="tactic">inversion</span> <span class="id" type="var">Hy<sub>2</sub></span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_PlusConstConst&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">H<sub>0</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">Hy<sub>1</sub></span>. <span class="id" type="tactic">inversion</span> <span class="id" type="var">Hy<sub>1</sub></span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_Plus1&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- (<span class="id" type="var">IHHy1</span> <span class="id" type="var">t<sub>1</sub>'0</span>).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">reflexivity</span>. <span class="id" type="tactic">assumption</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_Plus2&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">H</span> <span class="id" type="keyword">in</span> <span class="id" type="var">Hy<sub>1</sub></span>. <span class="id" type="tactic">inversion</span> <span class="id" type="var">Hy<sub>1</sub></span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;ST_Plus2&nbsp;*)</span> <span class="id" type="tactic">inversion</span> <span class="id" type="var">Hy<sub>2</sub></span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_PlusConstConst&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">Hy<sub>1</sub></span>. <span class="id" type="tactic">inversion</span> <span class="id" type="var">Hy<sub>1</sub></span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_Plus1&nbsp;*)</span> <span class="id" type="tactic">inversion</span> <span class="id" type="var">H<sub>2</sub></span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;ST_Plus2&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- (<span class="id" type="var">IHHy1</span> <span class="id" type="var">t<sub>2</sub>'0</span>).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">reflexivity</span>. <span class="id" type="tactic">assumption</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<br/>
<span class="id" type="keyword">End</span> <span class="id" type="var">SimpleArith2</span>.<br/>
</div>

<div class="doc">
可以看到在证明中有一些繁琐的重复。每次使用 <span class="inlinecode"><span class="id" type="tactic">inversion</span></span> <span class="inlinecode"><span class="id" type="var">Hy<sub>2</sub></span></span> 会产生
    三个子情形，但只有一个是相关的（匹配当前对 <span class="inlinecode"><span class="id" type="var">Hy<sub>1</sub></span></span> 归纳的那个情形）。
    剩下的两个子情形需要通过从假设中找到矛盾并对其反演来消解掉。

<div class="paragraph"> </div>

    下面自定义一个叫做 <span class="inlinecode"><span class="id" type="var">solve_by_inverts</span></span> 的策略可以简化这些情形。
    如果目标可以通过反演某些假设来解决，调用 <span class="inlinecode"><span class="id" type="var">solve_by_inverts</span></span> 会证明目标；
    否则，它会失败。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">solve_by_inverts</span> <span class="id" type="var">n</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> | <span class="id" type="var">H</span> : ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span> <span class="id" type="keyword">Prop</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">solve</span> [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">n</span> <span class="id" type="keyword">with</span> <span class="id" type="var">S</span> (<span class="id" type="var">S</span> (?<span class="id" type="var">n'</span>)) ⇒ <span class="id" type="tactic">subst</span>; <span class="id" type="var">solve_by_inverts</span> (<span class="id" type="var">S</span> <span class="id" type="var">n'</span>) <span class="id" type="keyword">end</span> ]<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
关于它是如何工作的细节目前不那么重要，但是它展示了 Coq 中 <span class="inlinecode"><span class="id" type="keyword">Ltac</span></span>
    语言的能力以及如何编写特殊目标的策略。它会在当前证明状态中找到一个具有类型
    <span class="inlinecode"><span class="id" type="keyword">Prop</span></span> （第二个 <span class="inlinecode"><span class="id" type="keyword">match</span></span>）的假设 <span class="inlinecode"><span class="id" type="var">H</span></span>（第一个 <span class="inlinecode"><span class="id" type="keyword">match</span></span>），然后对 <span class="inlinecode"><span class="id" type="var">H</span></span>
    进行反演（如果参数 <span class="inlinecode"><span class="id" type="var">n</span></span> 大于一，那么它会继续递归地调用这个策略）来完成当前目标。
    如果这样的假设不存在，这个策略会失败。

<div class="paragraph"> </div>

    我们通常会带上参数 <span class="inlinecode">1</span> 来调用 <span class="inlinecode"><span class="id" type="var">solve_by_inverts</span></span>（特别是很大的参数会导致
    长时间的证明检查），因此我们对它定义一个缩写 <span class="inlinecode"><span class="id" type="var">solve_by_invert</span></span>。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">solve_by_invert</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">solve_by_inverts</span> 1.<br/>
</div>

<div class="doc">
让我们看看这个策略如何简化之前定理的证明吧…… 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Module</span> <span class="id" type="var">SimpleArith3</span>.<br/>
<span class="id" type="keyword">Import</span> <span class="id" type="var">SimpleArith1</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">step_deterministic_alt</span>: <span class="id" type="var">deterministic</span> <span class="id" type="var">step</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">x</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">y<sub>2</sub></span> <span class="id" type="var">Hy<sub>1</sub></span> <span class="id" type="var">Hy<sub>2</sub></span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="tactic">dependent</span> <span class="id" type="var">y<sub>2</sub></span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">induction</span> <span class="id" type="var">Hy<sub>1</sub></span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">y<sub>2</sub></span> <span class="id" type="var">Hy<sub>2</sub></span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">Hy<sub>2</sub></span>; <span class="id" type="tactic">subst</span>; <span class="id" type="tactic">try</span> <span class="id" type="var">solve_by_invert</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;ST_PlusConstConst&nbsp;*)</span> <span class="id" type="tactic">reflexivity</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;ST_Plus1&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">IHHy1</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>2</sub></span>. <span class="id" type="tactic">rewrite</span> <span class="id" type="var">H<sub>2</sub></span>. <span class="id" type="tactic">reflexivity</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;ST_Plus2&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">IHHy1</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>2</sub></span>. <span class="id" type="tactic">rewrite</span> <span class="id" type="var">H<sub>2</sub></span>. <span class="id" type="tactic">reflexivity</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">End</span> <span class="id" type="var">SimpleArith3</span>.<br/>
</div>

<div class="doc">
<a name="lab137"></a><h2 class="section">值</h2>

<div class="paragraph"> </div>

 下一步，我们会使用“值”的概念来稍微重新表述一下单步归约的定义。
<div class="paragraph"> </div>

 为了更好地理解 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span> 关系，我们定义一个<b>抽象机（abstract machine）</b>:

<div class="paragraph"> </div>

<ul class="doclist">
<li> 在任意时刻，机器的<b>状态（state）</b>是一个项（term）。

<div class="paragraph"> </div>


</li>
<li> 机器的一<b>步（step）</b>是一个原子单元的计算，在这里，是一个“加法”操作。

<div class="paragraph"> </div>


</li>
<li> 机器的<b>停机状态（halting states）</b>是指没有后继计算的状态。 
</li>
</ul>

<div class="paragraph"> </div>

 我们可以通过以下方式来执行项 <span class="inlinecode"><span class="id" type="var">t</span></span>：

<div class="paragraph"> </div>

<ul class="doclist">
<li> 以 <span class="inlinecode"><span class="id" type="var">t</span></span> 作为机器的起始状态。

<div class="paragraph"> </div>


</li>
<li> 重复使用 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span> 关系来找到一个以 <span class="inlinecode"><span class="id" type="var">t</span></span> 开始的机器状态序列，序列中每个状态
        会转移到下一个。

<div class="paragraph"> </div>


</li>
<li> 当无法继续进行归约时，<b>输出（read out）</b>最终的机器状态作为执行的结果。  
</li>
</ul>

<div class="paragraph"> </div>

 直观地来说，可以看到机器的最终状态总是形如 <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n</span></span> 的项。
    我们把这些项叫做<b>值（values）</b>。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">value</span> : <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">v_const</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>, <span class="id" type="var">value</span> (<span class="id" type="var">C</span> <span class="id" type="var">n</span>).<br/>
</div>

<div class="doc">
在引入了值的概念后，我们可以使用它来更简洁地定义 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span>
    关系中的 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span> 规则： 
<div class="paragraph"> </div>

 <center><table class="infrule">
<tr class="infruleassumption">
  <td class="infrule">&nbsp;&nbsp;</td>
  <td class="infrulenamecol" rowspan="3">
    (ST_PlusConstConst) &nbsp;
  </td></tr>
<tr class="infrulemiddle">
  <td class="infrule"><hr /></td>
</tr>
<tr class="infruleassumption">
  <td class="infrule">P&nbsp;(C&nbsp;n<sub>1</sub>)&nbsp;(C&nbsp;n<sub>2</sub>)&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;C&nbsp;(n<sub>1</sub>&nbsp;+&nbsp;n<sub>2</sub>)</td>
  <td></td>
</td>
</table></center><center><table class="infrule">
<tr class="infruleassumption">
  <td class="infrule">t<sub>1</sub>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;t<sub>1</sub>'</td>
  <td class="infrulenamecol" rowspan="3">
    (ST_Plus1) &nbsp;
  </td></tr>
<tr class="infrulemiddle">
  <td class="infrule"><hr /></td>
</tr>
<tr class="infruleassumption">
  <td class="infrule">P&nbsp;t<sub>1</sub>&nbsp;t<sub>2</sub>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;P&nbsp;t<sub>1</sub>'&nbsp;t<sub>2</sub></td>
  <td></td>
</td>
</table></center><center><table class="infrule">
<tr class="infruleassumption">
  <td class="infrule">value&nbsp;v<sub>1</sub></td>
  <td></td>
</td>
<tr class="infruleassumption">
  <td class="infrule">t<sub>2</sub>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;t<sub>2</sub>'</td>
  <td class="infrulenamecol" rowspan="3">
    (ST_Plus2) &nbsp;
  </td></tr>
<tr class="infrulemiddle">
  <td class="infrule"><hr /></td>
</tr>
<tr class="infruleassumption">
  <td class="infrule">P&nbsp;v<sub>1</sub>&nbsp;t<sub>2</sub>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;P&nbsp;v<sub>1</sub>&nbsp;t<sub>2</sub>'</td>
  <td></td>
</td>
</table></center> 再一次地，变量名在这里包含了重要的信息：按照惯例，<span class="inlinecode"><span class="id" type="var">v<sub>1</sub></span></span> 涉及到值，
    而 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 涉及到任意的项。（在这种约定下，显式的 <span class="inlinecode"><span class="id" type="var">value</span></span> 假设也
    许是多余的。在这里仍然保留它，主要是为了在非形式化的和 Coq 的规则之间
    建立起密切的对应关系，但为简单起见，后面的非形式化规则中我们便会省略掉它。） 
<div class="paragraph"> </div>

  这些是形式化的规则： 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Reserved Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">step</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_PlusConstConst</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>2</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">C</span> (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">value</span> <span class="id" type="var">v<sub>1</sub></span> →                     <span class="comment">(*&nbsp;&lt;---&nbsp;n.b.&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub>'</span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " := (<span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/>
</div>

<div class="doc">
<a name="lab138"></a><h4 class="section">练习：3 星, standard, recommended (redo_determinism)</h4>
 作为这一改变的完备性检查，让我们重新验证一下确定性。
    下面是它的非形式化证明：

<div class="paragraph"> </div>

    <b>证明草稿</b>：我们必须证明如果 <span class="inlinecode"><span class="id" type="var">x</span></span> 向前一步可同时到 <span class="inlinecode"><span class="id" type="var">y<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">y<sub>2</sub></span></span>，
    那么 <span class="inlinecode"><span class="id" type="var">y<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">y<sub>2</sub></span></span> 相等。考虑 <span class="inlinecode"><span class="id" type="var">step</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">y<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">step</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">y<sub>2</sub></span></span> 生成式
    中最后使用的规则。

<div class="paragraph"> </div>

<ul class="doclist">
<li> 如果二者皆为 <span class="inlinecode"><span class="id" type="var">ST_PlusConstConst</span></span>，那么结果是显然的。

<div class="paragraph"> </div>


</li>
<li> 其中一个是 <span class="inlinecode"><span class="id" type="var">ST_PlusConstConst</span></span> 同时另一个是 <span class="inlinecode"><span class="id" type="var">ST_Plue1</span></span> 或 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span>
      的情形是不可能发生的，因为这蕴含了 <span class="inlinecode"><span class="id" type="var">x</span></span> 形如 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 而 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span>
      都是常量<b>且</b> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 或 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 中的一个形如 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">_</span></span>。

<div class="paragraph"> </div>


</li>
<li> 类似地，一个是 <span class="inlinecode"><span class="id" type="var">ST_Plus1</span></span> 同时另一个是 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span> 的情形也不可能发生，
      因为这蕴含了 <span class="inlinecode"><span class="id" type="var">x</span></span> 形如 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 而 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 既形如 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>11</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>12</sub></span></span> 又是值
      （因此形如 <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n</span></span>）。

<div class="paragraph"> </div>


</li>
<li> 对于两个导出式都以 <span class="inlinecode"><span class="id" type="var">ST_Plus1</span></span> 或 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span> 结束的情形，可直接从归纳假设中得证。<span class="proofbox">&#9744;</span> 
</li>
</ul>

<div class="paragraph"> </div>

 本证明中大部分与之前的相同。但为了最大化练习的收益，你应该从零写下形式化的版本，
    只有当卡住时再去回顾之前的证明。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">step_deterministic</span> :<br/>
&nbsp;&nbsp;<span class="id" type="var">deterministic</span> <span class="id" type="var">step</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 

<div class="doc">
<a name="lab139"></a><h2 class="section">强可进性和正规式</h2>

<div class="paragraph"> </div>

 这个玩具语言的单步归约定义是十分简单的，但是对于大一点的语言，往往会出现
    因为忘记某个规则而导致一些项虽然还不是值但已无法继续前进归约的情况。下面的定理
    说明了我们没有犯这样的错误。 
<div class="paragraph"> </div>

 <b>定理</b>（<b>强可进性</b>（Strong Progress））：如果 <span class="inlinecode"><span class="id" type="var">t</span></span> 是一个项，那么 <span class="inlinecode"><span class="id" type="var">t</span></span>
    要么是一个值，要么存在项 <span class="inlinecode"><span class="id" type="var">t'</span></span> 使 <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span> <span class="inlinecode"><span class="id" type="var">t'</span></span>。
<div class="paragraph"> </div>

 <b>证明</b>：对 <span class="inlinecode"><span class="id" type="var">t</span></span> 进行归纳。

<div class="paragraph"> </div>

<ul class="doclist">
<li> 假设 <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n</span></span>。那么 <span class="inlinecode"><span class="id" type="var">t</span></span> 是值。

<div class="paragraph"> </div>


</li>
<li> 假设 Suppose <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span>，其中 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 或是值，或可前进到某个 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub>'</span></span>；
      <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 或是值，或可前进到某个 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub>'</span></span>（根据 <span class="inlinecode"><span class="id" type="var">IH</span></span>）。我们需要证明 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 要么是值，
      要么可前进到某个 <span class="inlinecode"><span class="id" type="var">t'</span></span>

<div class="paragraph"> </div>

<ul class="doclist">
<li> 如果 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 都是值，那么根据 <span class="inlinecode"><span class="id" type="var">ST_PlusConstConst</span></span> 得 <span class="inlinecode"><span class="id" type="var">t</span></span> 可前进一步。

<div class="paragraph"> </div>


</li>
<li> 如果 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 是值且 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 可前进一步，那么根据 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span> 得 <span class="inlinecode"><span class="id" type="var">t</span></span> 可前进一步。

<div class="paragraph"> </div>


</li>
<li> 如果 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 可前进一步，那么根据 <span class="inlinecode"><span class="id" type="var">ST_Plus1</span></span> 得 <span class="inlinecode"><span class="id" type="var">t</span></span> 可前进一步。 <span class="proofbox">&#9744;</span>

</li>
</ul>

</li>
</ul>

<div class="paragraph"> </div>

   或者，形式化地说： 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">strong_progress</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">value</span> <span class="id" type="var">t</span> ∨ (<span style='font-size:120%;'>&exist;</span><span class="id" type="var">t'</span>, <span class="id" type="var">t</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t'</span>).<br/>
<div class="togglescript" id="proofcontrol3" onclick="toggleDisplay('proof3');toggleDisplay('proofcontrol3')"><span class="show"></span></div>
<div class="proofscript" id="proof3" onclick="toggleDisplay('proof3');toggleDisplay('proofcontrol3')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">induction</span> <span class="id" type="var">t</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;C&nbsp;*)</span> <span class="id" type="var">left</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">v_const</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;P&nbsp;*)</span> <span class="id" type="var">right</span>. <span class="id" type="tactic">destruct</span> <span class="id" type="var">IHt1</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">IHt1</span> | [<span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">Ht<sub>1</sub></span>]].<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;l&nbsp;*)</span> <span class="id" type="tactic">destruct</span> <span class="id" type="var">IHt2</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">IHt2</span> | [<span class="id" type="var">t<sub>2</sub>'</span> <span class="id" type="var">Ht<sub>2</sub></span>]].<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <span class="comment">(*&nbsp;l&nbsp;*)</span> <span class="id" type="tactic">inversion</span> <span class="id" type="var">IHt1</span>. <span class="id" type="tactic">inversion</span> <span class="id" type="var">IHt2</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">C</span> (<span class="id" type="var">n</span> + <span class="id" type="var">n<sub>0</sub></span>)).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <span class="comment">(*&nbsp;r&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub>'</span>).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">IHt1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">Ht<sub>2</sub></span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;r&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">Ht<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
这个重要的定理叫做<b>强可进性（strong progress）</b>，因为每个项
    要么是值，要么可“前进”到某个其他的项。（修饰语“强”区分另一个不同的版本，
    叫做<b>可进性</b>，我们在后面的章节中会学校到。） 
<div class="paragraph"> </div>

 通过扩展“做出前进”这个概念，我们可以得到一些关于值有趣的事实：在本语言中，
    从这个意义上讲，值是<b>不能</b>够继续前进的项。

<div class="paragraph"> </div>

    为了形式化地表述这个观察，让我们给不能前进的项起个名字。我们把它叫做
    <b>正规式（normal forms）</b>。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">normal_form</span> {<span class="id" type="var">X</span> : <span class="id" type="keyword">Type</span>} (<span class="id" type="var">R</span> : <span class="id" type="var">relation</span> <span class="id" type="var">X</span>) (<span class="id" type="var">t</span> : <span class="id" type="var">X</span>) : <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;¬<span style='font-size:120%;'>&exist;</span><span class="id" type="var">t'</span>, <span class="id" type="var">R</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>.<br/>
</div>

<div class="doc">
请注意这个定义规范了对任意集合 <span class="inlinecode"><span class="id" type="var">X</span></span> 上的任意关系 <span class="inlinecode"><span class="id" type="var">R</span></span> 的正规式，而不仅仅是我们
    这里关心的某个单步归约关系的正规式。后面的课程讨论其他关系时我们会继续使用这个术语。 
<div class="paragraph"> </div>

 我们可以使用这个术语来一般化对于强可进性定理的观察：在这个语言中，
    正规式和值实际上是同一个东西。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Lemma</span> <span class="id" type="var">value_is_nf</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">v</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">value</span> <span class="id" type="var">v</span> → <span class="id" type="var">normal_form</span> <span class="id" type="var">step</span> <span class="id" type="var">v</span>.<br/>
<div class="togglescript" id="proofcontrol4" onclick="toggleDisplay('proof4');toggleDisplay('proofcontrol4')"><span class="show"></span></div>
<div class="proofscript" id="proof4" onclick="toggleDisplay('proof4');toggleDisplay('proofcontrol4')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">normal_form</span>. <span class="id" type="tactic">intros</span> <span class="id" type="var">v</span> <span class="id" type="var">H</span>. <span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">contra</span>. <span class="id" type="tactic">inversion</span> <span class="id" type="var">contra</span>. <span class="id" type="tactic">inversion</span> <span class="id" type="var">H<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<br/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">nf_is_value</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">normal_form</span> <span class="id" type="var">step</span> <span class="id" type="var">t</span> → <span class="id" type="var">value</span> <span class="id" type="var">t</span>.<br/>
<div class="togglescript" id="proofcontrol5" onclick="toggleDisplay('proof5');toggleDisplay('proofcontrol5')"><span class="show"></span></div>
<div class="proofscript" id="proof5" onclick="toggleDisplay('proof5');toggleDisplay('proofcontrol5')">
<span class="id" type="keyword">Proof</span>. <span class="comment">(*&nbsp;a&nbsp;corollary&nbsp;of&nbsp;<span class="inlinecode"><span class="id" type="var">strong_progress</span></span>...&nbsp;*)</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">normal_form</span>. <span class="id" type="tactic">intros</span> <span class="id" type="var">t</span> <span class="id" type="var">H</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">assert</span> (<span class="id" type="var">G</span> : <span class="id" type="var">value</span> <span class="id" type="var">t</span> ∨ <span style='font-size:120%;'>&exist;</span><span class="id" type="var">t'</span>, <span class="id" type="var">t</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t'</span>).<br/>
&nbsp;&nbsp;{ <span class="id" type="tactic">apply</span> <span class="id" type="var">strong_progress</span>. }<br/>
&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">G</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">G</span> | <span class="id" type="var">G</span>].<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;l&nbsp;*)</span> <span class="id" type="tactic">apply</span> <span class="id" type="var">G</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;r&nbsp;*)</span> <span class="id" type="var">exfalso</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">H</span>. <span class="id" type="tactic">assumption</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<br/>
<span class="id" type="keyword">Corollary</span> <span class="id" type="var">nf_same_as_value</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">normal_form</span> <span class="id" type="var">step</span> <span class="id" type="var">t</span> ↔ <span class="id" type="var">value</span> <span class="id" type="var">t</span>.<br/>
<div class="togglescript" id="proofcontrol6" onclick="toggleDisplay('proof6');toggleDisplay('proofcontrol6')"><span class="show"></span></div>
<div class="proofscript" id="proof6" onclick="toggleDisplay('proof6');toggleDisplay('proofcontrol6')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">split</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">nf_is_value</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">value_is_nf</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
这个为什么值得注意呢？

<div class="paragraph"> </div>

    因为 <span class="inlinecode"><span class="id" type="var">value</span></span> 是一个语法概念——它是由项的形式定义的——然而 <span class="inlinecode"><span class="id" type="var">normal_form</span></span> 是一个
    语义概念——它是由项如何前进定义的。

<div class="paragraph"> </div>

    并不显然这两个概念应当一致！ 
<div class="paragraph"> </div>

 确实，容易错误地写下使它们<b>不</b>一致的定义。 
<div class="paragraph"> </div>

<a name="lab140"></a><h4 class="section">练习：3 星, standard, optional (value_not_same_as_normal_form1)</h4>
 我们可能错误地定义了 <span class="inlinecode"><span class="id" type="var">value</span></span> 使它包括了还没有完成归约的项。  （如果你不想亲自动手在 Coq 中完成这个和下一个练习，
    也请思考一下，尝试找到一个这样的项。）
</div>
<div class="code code-tight">

<span class="id" type="keyword">Module</span> <span class="id" type="var">Temp1</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">value</span> : <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">v_const</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>, <span class="id" type="var">value</span> (<span class="id" type="var">C</span> <span class="id" type="var">n</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">v_funny</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">value</span> (<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>2</sub></span>)). <span class="comment">(*&nbsp;&lt;---&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Reserved Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">step</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_PlusConstConst</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>2</sub></span>) <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">C</span> (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">value</span> <span class="id" type="var">v<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub>'</span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " := (<span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">value_not_same_as_normal_form</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">v</span>, <span class="id" type="var">value</span> <span class="id" type="var">v</span> ∧ ¬<span class="id" type="var">normal_form</span> <span class="id" type="var">step</span> <span class="id" type="var">v</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
<span class="id" type="keyword">End</span> <span class="id" type="var">Temp1</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 

<div class="doc">
<a name="lab141"></a><h4 class="section">练习：2 星, standard, optional (value_not_same_as_normal_form2)</h4>
 或许，我们错误地定义了 <span class="inlinecode"><span class="id" type="var">step</span></span> 使它允许继续归约一个值。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Module</span> <span class="id" type="var">Temp2</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">value</span> : <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">v_const</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>, <span class="id" type="var">value</span> (<span class="id" type="var">C</span> <span class="id" type="var">n</span>). <span class="comment">(*&nbsp;Original&nbsp;definition&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Reserved Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">step</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Funny</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">C</span> <span class="id" type="var">n</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n</span>) (<span class="id" type="var">C</span> 0)                  <span class="comment">(*&nbsp;&lt;---&nbsp;NEW&nbsp;*)</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_PlusConstConst</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>2</sub></span>) <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">C</span> (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">value</span> <span class="id" type="var">v<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub>'</span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " := (<span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">value_not_same_as_normal_form</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">v</span>, <span class="id" type="var">value</span> <span class="id" type="var">v</span> ∧ ¬<span class="id" type="var">normal_form</span> <span class="id" type="var">step</span> <span class="id" type="var">v</span>.<br/>
<div class="togglescript" id="proofcontrol7" onclick="toggleDisplay('proof7');toggleDisplay('proofcontrol7')"><span class="show"></span></div>
<div class="proofscript" id="proof7" onclick="toggleDisplay('proof7');toggleDisplay('proofcontrol7')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>
<span class="id" type="keyword">End</span> <span class="id" type="var">Temp2</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab142"></a><h4 class="section">练习：3 星, standard, optional (value_not_same_as_normal_form3)</h4>
 最后，我们还可能通过 <span class="inlinecode"><span class="id" type="var">value</span></span> 和 <span class="inlinecode"><span class="id" type="var">step</span></span> 定义了某些不是值但已无法继续由
    <span class="inlinecode"><span class="id" type="var">step</span></span> 关系进行归约的项。这些项被称作<b>卡住了（stuck）</b>。在这种情况是由语义
    中的错误导致的，但我们也会看到一些情况，即使是正确的语言定义中也会允许一些项卡住。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Module</span> <span class="id" type="var">Temp3</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">value</span> : <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">v_const</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>, <span class="id" type="var">value</span> (<span class="id" type="var">C</span> <span class="id" type="var">n</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Reserved Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">step</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_PlusConstConst</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>2</sub></span>) <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">C</span> (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " := (<span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/>
</div>

<div class="doc">
（请注意 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span> 是未定义的。） 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Lemma</span> <span class="id" type="var">value_not_same_as_normal_form</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">t</span>, ¬<span class="id" type="var">value</span> <span class="id" type="var">t</span> ∧ <span class="id" type="var">normal_form</span> <span class="id" type="var">step</span> <span class="id" type="var">t</span>.<br/>
<div class="togglescript" id="proofcontrol8" onclick="toggleDisplay('proof8');toggleDisplay('proofcontrol8')"><span class="show"></span></div>
<div class="proofscript" id="proof8" onclick="toggleDisplay('proof8');toggleDisplay('proofcontrol8')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<br/>
<span class="id" type="keyword">End</span> <span class="id" type="var">Temp3</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 

<div class="doc">
<a name="lab143"></a><h3 class="section">额外练习</h3>

</div>
<div class="code code-space">

<br/>
<span class="id" type="keyword">Module</span> <span class="id" type="var">Temp4</span>.<br/>
</div>

<div class="doc">
这是另一个非常简单的语言，其项并不是数字和加法表达式，而是布尔值真和假，
    以及条件表达式…… 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">tm</span> : <span class="id" type="keyword">Type</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">tru</span> : <span class="id" type="var">tm</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">fls</span> : <span class="id" type="var">tm</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">test</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">value</span> : <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">v_tru</span> : <span class="id" type="var">value</span> <span class="id" type="var">tru</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">v_fls</span> : <span class="id" type="var">value</span> <span class="id" type="var">fls</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Reserved Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">step</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_IfTrue</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">tru</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_IfFalse</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">fls</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_If</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">test</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " := (<span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/>
</div>

<div class="doc">
<a name="lab144"></a><h4 class="section">练习：1 星, standard (smallstep_bools)</h4>
 下列哪些命题是可被证明的？（这只是一个思考练习，但如果你想挑战一下自己，
    可以尝试在 Coq 中证明你的答案。） 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">bool_step_prop1</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fls</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">fls</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">bool_step_prop2</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">tru</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">test</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">test</span> <span class="id" type="var">fls</span> <span class="id" type="var">fls</span> <span class="id" type="var">fls</span>)<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">tru</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">bool_step_prop3</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">test</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">test</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fls</span><br/>
&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">tru</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">test</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fls</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;请勿修改下面这一行：&nbsp;*)</span><br/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">manual_grade_for_smallstep_bools</span> : <span class="id" type="var">option</span> (<span class="id" type="var">nat</span>*<span class="id" type="var">string</span>) := <span class="id" type="var">None</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab145"></a><h4 class="section">练习：3 星, standard, optional (progress_bool)</h4>
 我们之前对加法表达式证明了其可进性，我们也可以证明布尔表达式的可进性。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">strong_progress</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">value</span> <span class="id" type="var">t</span> ∨ (<span style='font-size:120%;'>&exist;</span><span class="id" type="var">t'</span>, <span class="id" type="var">t</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t'</span>).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab146"></a><h4 class="section">练习：2 星, standard, optional (step_deterministic)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">step_deterministic</span> :<br/>
&nbsp;&nbsp;<span class="id" type="var">deterministic</span> <span class="id" type="var">step</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="code code-tight">

<span class="id" type="keyword">Module</span> <span class="id" type="var">Temp5</span>.<br/>
</div>

<div class="doc">
<a name="lab147"></a><h4 class="section">练习：2 星, standard (smallstep_bool_shortcut)</h4>
 假设我们想要为布尔表达式的单步归约关系添加“短路（short circuit）”，
    这样当条件语句的 <span class="inlinecode"><span class="id" type="keyword">then</span></span> 和 <span class="inlinecode"><span class="id" type="keyword">else</span></span> 分支有相同的值时（<span class="inlinecode"><span class="id" type="var">tru</span></span> 或 <span class="inlinecode"><span class="id" type="var">fls</span></span>），
    便可以用一步化简整个条件表达式到值，尽管其条件还没有被归约到某个值。
    比如，我们想要下面的命题可被证明：

<div class="paragraph"> </div>

<div class="code code-tight">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">test</span>&nbsp;<span class="id" type="var">tru</span>&nbsp;<span class="id" type="var">tru</span>&nbsp;<span class="id" type="var">tru</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fls</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fls</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fls</span>.
<div class="paragraph"> </div>

</div>

<div class="paragraph"> </div>

 请为单步关系添加一个额外的语句来达到这个目的，并证明 <span class="inlinecode"><span class="id" type="var">bool_step_prop4</span></span>。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Reserved Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">step</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_IfTrue</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">tru</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_IfFalse</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">fls</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_If</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">test</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span><br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " := (<span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">bool_step_prop4</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">test</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span> <span class="id" type="var">tru</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fls</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fls</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fls</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Example</span> <span class="id" type="var">bool_step_prop4_holds</span> :<br/>
&nbsp;&nbsp;<span class="id" type="var">bool_step_prop4</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab148"></a><h4 class="section">练习：3 星, standard, optional (properties_of_altered_step)</h4>
 课程中证明的确定性和强可进性定理对于我们刚刚定义的单步关系也是成立的。
    在我们添加了 <span class="inlinecode"><span class="id" type="var">ST_ShortCircuit</span></span> 以后……

<div class="paragraph"> </div>

<ul class="doclist">
<li> <span class="inlinecode"><span class="id" type="var">step</span></span> 关系是否仍然是确定的？请回答是或否，并简要解释（一句话即可）你的答案。

<div class="paragraph"> </div>

      可选：在 Coq 中证明你的答案。
</li>
</ul>

</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/>
</div>

<div class="doc">

<div class="paragraph"> </div>

<ul class="doclist">
<li> 强可进性是否成立？请回答是或否，并简要解释（一句话即可）你的答案。

<div class="paragraph"> </div>

     可选：在 Coq 中证明你的答案。

</li>
</ul>

</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/>
</div>

<div class="doc">

<div class="paragraph"> </div>

<ul class="doclist">
<li> 一般来说，如果从原始的单步关系中拿掉一两个构造子，能否使强可进性不再成立？
     请回答是或否，并简要解释（一句话即可）你的答案。

</li>
</ul>

<div class="paragraph"> </div>

<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/>
 <span class="proofbox">&#9744;</span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">End</span> <span class="id" type="var">Temp5</span>.<br/>
<span class="id" type="keyword">End</span> <span class="id" type="var">Temp4</span>.<br/>
</div>

<div class="doc">
<a name="lab149"></a><h1 class="section">多步归约</h1>

<div class="paragraph"> </div>

 目前为止，我们学习的是<b>单步归约（single-step reduction）</b>关系 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span>，
    它形式化了抽象机执行程序的每一步。

<div class="paragraph"> </div>

    我们可以使用同一个机器来归约程序直到结束——得到它最后的结果。我们这样形式化它：

<div class="paragraph"> </div>

<ul class="doclist">
<li> 首先，我们定义一个<b>多步归约关系（multi-step reduction relation）</b>
      <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span>，如果项 <span class="inlinecode"><span class="id" type="var">t</span></span> 可在任意多的单步（包括零步）内到达 <span class="inlinecode"><span class="id" type="var">t'</span></span>，那么它关联起
      <span class="inlinecode"><span class="id" type="var">t</span></span> 和 <span class="inlinecode"><span class="id" type="var">t'</span></span>。

<div class="paragraph"> </div>


</li>
<li> 接着我们定义 <span class="inlinecode"><span class="id" type="var">t</span></span> 的“结果（result）”是一个 <span class="inlinecode"><span class="id" type="var">t</span></span> 可用多步达到的正规式。
</li>
</ul>

</div>

<div class="doc">
因为我们会反复使用多步归约这个概念，让我们花点功夫一般化地定义它。

<div class="paragraph"> </div>

    如下，给定关系 <span class="inlinecode"><span class="id" type="var">R</span></span>（当前为 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span>），我们定义关系 <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">R</span></span> 是 <span class="inlinecode"><span class="id" type="var">R</span></span>
    的<b>多步闭包（multi-step closure）</b>。
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">multi</span> {<span class="id" type="var">X</span> : <span class="id" type="keyword">Type</span>} (<span class="id" type="var">R</span> : <span class="id" type="var">relation</span> <span class="id" type="var">X</span>) : <span class="id" type="var">relation</span> <span class="id" type="var">X</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">multi_refl</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x</span> : <span class="id" type="var">X</span>), <span class="id" type="var">multi</span> <span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">x</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">multi_step</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x</span> <span class="id" type="var">y</span> <span class="id" type="var">z</span> : <span class="id" type="var">X</span>),<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">multi</span> <span class="id" type="var">R</span> <span class="id" type="var">y</span> <span class="id" type="var">z</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">multi</span> <span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">z</span>.<br/>
</div>

<div class="doc">
（在<b>逻辑基础</b>的 <a href="https://coq-zh.github.io/SF-zh/lf-current/Rel.html"><span class="inlineref">Rel</span></a> 一章和 Coq 标准库中，这个关系叫做
    <span class="inlinecode"><span class="id" type="var">clos_refl_trans_1n</span></span>。出于可读性的考虑，我们给出一个简短的名字。） 
<div class="paragraph"> </div>

 这个定义的作用是 <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">R</span></span> 关联起两个元素 <span class="inlinecode"><span class="id" type="var">x</span></span> 和 <span class="inlinecode"><span class="id" type="var">y</span></span>，如果

<div class="paragraph"> </div>

<ul class="doclist">
<li> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">y</span></span>，或

</li>
<li> <span class="inlinecode"><span class="id" type="var">R</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">y</span></span>，或

</li>
<li> 存在某个非空序列 <span class="inlinecode"><span class="id" type="var">z<sub>1</sub></span></span>,<span class="inlinecode"><span class="id" type="var">z<sub>2</sub></span></span>, ..., <span class="inlinecode"><span class="id" type="var">zn</span></span> 使得

<div class="paragraph"> </div>

<div class="code code-tight">
&nbsp;&nbsp;<span class="id" type="var">R</span>&nbsp;<span class="id" type="var">x</span>&nbsp;<span class="id" type="var">z<sub>1</sub></span><br/>
&nbsp;&nbsp;<span class="id" type="var">R</span>&nbsp;<span class="id" type="var">z<sub>1</sub></span>&nbsp;<span class="id" type="var">z<sub>2</sub></span><br/>
&nbsp;&nbsp;...<br/>
&nbsp;&nbsp;<span class="id" type="var">R</span>&nbsp;<span class="id" type="var">zn</span>&nbsp;<span class="id" type="var">y</span>.
<div class="paragraph"> </div>

</div>

</li>
</ul>
    因此，如果 <span class="inlinecode"><span class="id" type="var">R</span></span> 刻画了单步计算，那么 <span class="inlinecode"><span class="id" type="var">z<sub>1</sub></span></span> ... <span class="inlinecode"><span class="id" type="var">zn</span></span> 则是 <span class="inlinecode"><span class="id" type="var">x</span></span> 和 <span class="inlinecode"><span class="id" type="var">y</span></span>
    的中间计算步骤。 
<div class="paragraph"> </div>

 我们为关系 <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">step</span></span> 使用记号 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span>。
</div>
<div class="code code-tight">

<span class="id" type="keyword">Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>' t' " := (<span class="id" type="var">multi</span> <span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>) (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/>
</div>

<div class="doc">
关系 <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">R</span></span> 具有多个重要的性质。

<div class="paragraph"> </div>

    首先，显然它是<b>自反的（reflexive）</b>（即 <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">x</span>,</span> <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">R</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span>）。
    就 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span> 关系（即 <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">step</span></span>）而言，可以直观地理解为一个项可以执行零步
    到它自己。 
<div class="paragraph"> </div>

 第二，它包含了 <span class="inlinecode"><span class="id" type="var">R</span></span>——也即，单步执行是多步执行的一个特殊情况。（这个事实解释了
    “<span class="inlinecode"><span class="id" type="var">R</span></span> 的多步闭包（multi-step closure）”中的“闭包（closure）”一词。） 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">multi_R</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">X</span> : <span class="id" type="keyword">Type</span>) (<span class="id" type="var">R</span> : <span class="id" type="var">relation</span> <span class="id" type="var">X</span>) (<span class="id" type="var">x</span> <span class="id" type="var">y</span> : <span class="id" type="var">X</span>),<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span> → (<span class="id" type="var">multi</span> <span class="id" type="var">R</span>) <span class="id" type="var">x</span> <span class="id" type="var">y</span>.<br/>
<div class="togglescript" id="proofcontrol9" onclick="toggleDisplay('proof9');toggleDisplay('proofcontrol9')"><span class="show"></span></div>
<div class="proofscript" id="proof9" onclick="toggleDisplay('proof9');toggleDisplay('proofcontrol9')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">X</span> <span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span> <span class="id" type="var">H</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_step</span> <span class="id" type="keyword">with</span> <span class="id" type="var">y</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">H</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">multi_refl</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
第三， <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">R</span></span> 是<b>传递的（transitive）</b>。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">multi_trans</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">X</span> : <span class="id" type="keyword">Type</span>) (<span class="id" type="var">R</span> : <span class="id" type="var">relation</span> <span class="id" type="var">X</span>) (<span class="id" type="var">x</span> <span class="id" type="var">y</span> <span class="id" type="var">z</span> : <span class="id" type="var">X</span>),<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">multi</span> <span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span>  →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">multi</span> <span class="id" type="var">R</span> <span class="id" type="var">y</span> <span class="id" type="var">z</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">multi</span> <span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">z</span>.<br/>
<div class="togglescript" id="proofcontrol10" onclick="toggleDisplay('proof10');toggleDisplay('proofcontrol10')"><span class="show"></span></div>
<div class="proofscript" id="proof10" onclick="toggleDisplay('proof10');toggleDisplay('proofcontrol10')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">X</span> <span class="id" type="var">R</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span> <span class="id" type="var">z</span> <span class="id" type="var">G</span> <span class="id" type="var">H</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">induction</span> <span class="id" type="var">G</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;- <span class="comment">(*&nbsp;multi_refl&nbsp;*)</span> <span class="id" type="tactic">assumption</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;- <span class="comment">(*&nbsp;multi_step&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_step</span> <span class="id" type="keyword">with</span> <span class="id" type="var">y</span>. <span class="id" type="tactic">assumption</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">IHG</span>. <span class="id" type="tactic">assumption</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
特别地，对于项的 <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">step</span></span> 关系可得，如果 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 且 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>3</sub></span></span>，
    那么 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>3</sub></span></span>。
</div>

<div class="doc">
<a name="lab150"></a><h2 class="section">例子</h2>

<div class="paragraph"> </div>

 这里有一些 <span class="inlinecode"><span class="id" type="var">multi</span></span> <span class="inlinecode"><span class="id" type="var">step</span></span> 关系的例子： 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Lemma</span> <span class="id" type="var">test_multistep_1</span>:<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 0) (<span class="id" type="var">C</span> 3))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 2) (<span class="id" type="var">C</span> 4))<br/>
&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">C</span> ((0 + 3) + (2 + 4)).<br/>
<div class="togglescript" id="proofcontrol11" onclick="toggleDisplay('proof11');toggleDisplay('proofcontrol11')"><span class="show"></span></div>
<div class="proofscript" id="proof11" onclick="toggleDisplay('proof11');toggleDisplay('proofcontrol11')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_step</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> (0 + 3))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 2) (<span class="id" type="var">C</span> 4))).<br/>
&nbsp;&nbsp;{ <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>. }<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_step</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> (0 + 3))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> (2 + 4))).<br/>
&nbsp;&nbsp;{ <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">v_const</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>. }<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_R</span>.<br/>
&nbsp;&nbsp;{ <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>. }<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
这是使用 <span class="inlinecode"><span class="id" type="tactic">eapply</span></span> 的另一种证明方法，可以避免显式地构造所有的中间项。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Lemma</span> <span class="id" type="var">test_multistep_1'</span>:<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 0) (<span class="id" type="var">C</span> 3))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 2) (<span class="id" type="var">C</span> 4))<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">C</span> ((0 + 3) + (2 + 4)).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. { <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>. }<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. { <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">v_const</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>. }<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. { <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>. }<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_refl</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<div class="doc">
<a name="lab151"></a><h4 class="section">练习：1 星, standard, optional (test_multistep_2)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">test_multistep_2</span>:<br/>
&nbsp;&nbsp;<span class="id" type="var">C</span> 3 <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">C</span> 3.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab152"></a><h4 class="section">练习：1 星, standard, optional (test_multistep_3)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">test_multistep_3</span>:<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 0) (<span class="id" type="var">C</span> 3)<br/>
&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 0) (<span class="id" type="var">C</span> 3).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab153"></a><h4 class="section">练习：2 星, standard (test_multistep_4)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">test_multistep_4</span>:<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> 0)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> 2)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 0) (<span class="id" type="var">C</span> 3)))<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> 0)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">C</span> (2 + (0 + 3))).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 

<div class="doc">
<a name="lab154"></a><h2 class="section">再谈正规式</h2>

<div class="paragraph"> </div>

 如果 <span class="inlinecode"><span class="id" type="var">t</span></span> 可在零步或多步归约到 <span class="inlinecode"><span class="id" type="var">t'</span></span> 且 <span class="inlinecode"><span class="id" type="var">t'</span></span> 是一个正规式，那么我们说
    “<span class="inlinecode"><span class="id" type="var">t'</span></span> 是 <span class="inlinecode"><span class="id" type="var">t</span></span> 的一个正规式”。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">step_normal_form</span> := <span class="id" type="var">normal_form</span> <span class="id" type="var">step</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">normal_form_of</span> (<span class="id" type="var">t</span> <span class="id" type="var">t'</span> : <span class="id" type="var">tm</span>) :=<br/>
&nbsp;&nbsp;(<span class="id" type="var">t</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">t'</span> ∧ <span class="id" type="var">step_normal_form</span> <span class="id" type="var">t'</span>).<br/>
</div>

<div class="doc">
我们已经看到，这这个语言中，单步归约是确定的——也即，给定的项最多只有一种方法
    前进一步。从中可推论，如果 <span class="inlinecode"><span class="id" type="var">t</span></span> 可以到到某个正规式，那么这个正规式唯一。换句话说，
    我们实际上可以把 <span class="inlinecode"><span class="id" type="var">normal_form</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">t'</span></span> 理解为“<span class="inlinecode"><span class="id" type="var">t'</span></span> <b>就是</b> <span class="inlinecode"><span class="id" type="var">t</span></span> 的正规式”。
<div class="paragraph"> </div>

<a name="lab155"></a><h4 class="section">练习：3 星, standard, optional (normal_forms_unique)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">normal_forms_unique</span>:<br/>
&nbsp;&nbsp;<span class="id" type="var">deterministic</span> <span class="id" type="var">normal_form_of</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;我们推荐以这样的方式开始证明。&nbsp;*)</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">deterministic</span>. <span class="id" type="tactic">unfold</span> <span class="id" type="var">normal_form_of</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">x</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">y<sub>2</sub></span> <span class="id" type="var">P<sub>1</sub></span> <span class="id" type="var">P<sub>2</sub></span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">P<sub>1</sub></span> <span class="id" type="keyword">as</span> [<span class="id" type="var">P<sub>11</sub></span> <span class="id" type="var">P<sub>12</sub></span>]; <span class="id" type="tactic">clear</span> <span class="id" type="var">P<sub>1</sub></span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">P<sub>2</sub></span> <span class="id" type="keyword">as</span> [<span class="id" type="var">P<sub>21</sub></span> <span class="id" type="var">P<sub>22</sub></span>]; <span class="id" type="tactic">clear</span> <span class="id" type="var">P<sub>2</sub></span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="tactic">dependent</span> <span class="id" type="var">y<sub>2</sub></span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

 确实，这个语言中还具备更强的性质（尽管不是所有语言都具备）：
    任意项 <span class="inlinecode"><span class="id" type="var">t</span></span> 最终都会到达一个正规式——即，<span class="inlinecode"><span class="id" type="var">normal_form_of</span></span> 是一个全函数。
    形式化地讲，我们说 <span class="inlinecode"><span class="id" type="var">step</span></span> 关系是<b>正规化（normalizing）</b>的。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">normalizing</span> {<span class="id" type="var">X</span> : <span class="id" type="keyword">Type</span>} (<span class="id" type="var">R</span> : <span class="id" type="var">relation</span> <span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span>, <span style='font-size:120%;'>&exist;</span><span class="id" type="var">t'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">multi</span> <span class="id" type="var">R</span>) <span class="id" type="var">t</span> <span class="id" type="var">t'</span> ∧ <span class="id" type="var">normal_form</span> <span class="id" type="var">R</span> <span class="id" type="var">t'</span>.<br/>
</div>

<div class="doc">
为了证明 <span class="inlinecode"><span class="id" type="var">step</span></span> 的正规性，我们需要几个引理。

<div class="paragraph"> </div>

    首先，我们观察到如果 <span class="inlinecode"><span class="id" type="var">t</span></span> 以多步归约到 <span class="inlinecode"><span class="id" type="var">t'</span></span>，那么当 <span class="inlinecode"><span class="id" type="var">t</span></span> 出现为 <span class="inlinecode"><span class="id" type="var">P</span></span> 节点的左子节点时，
    可以使用同一个 <span class="inlinecode"><span class="id" type="var">t</span></span> 的归约序列。同理，当 <span class="inlinecode"><span class="id" type="var">P</span></span> 的左子节点为值时，若 <span class="inlinecode"><span class="id" type="var">t</span></span> 出现为 <span class="inlinecode"><span class="id" type="var">P</span></span>
    的右子节点也适用。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Lemma</span> <span class="id" type="var">multistep_congr_1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>.<br/>
<div class="togglescript" id="proofcontrol12" onclick="toggleDisplay('proof12');toggleDisplay('proofcontrol12')"><span class="show"></span></div>
<div class="proofscript" id="proof12" onclick="toggleDisplay('proof12');toggleDisplay('proofcontrol12')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">H</span>. <span class="id" type="tactic">induction</span> <span class="id" type="var">H</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;multi_refl&nbsp;*)</span> <span class="id" type="tactic">apply</span> <span class="id" type="var">multi_refl</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;multi_step&nbsp;*)</span> <span class="id" type="tactic">apply</span> <span class="id" type="var">multi_step</span> <span class="id" type="keyword">with</span> (<span class="id" type="var">P</span> <span class="id" type="var">y</span> <span class="id" type="var">t<sub>2</sub></span>).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">H</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="id" type="tactic">apply</span> <span class="id" type="var">IHmulti</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
<a name="lab156"></a><h4 class="section">练习：2 星, standard (multistep_congr_2)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">multistep_congr_2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">value</span> <span class="id" type="var">t<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">t<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub>'</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

 使用这些引理，证明的主体是直接进行归纳。

<div class="paragraph"> </div>

    <b>定理</b>：<span class="inlinecode"><span class="id" type="var">step</span></span> 函数是正规化的——即，对于每个 <span class="inlinecode"><span class="id" type="var">t</span></span> 存在某个 <span class="inlinecode"><span class="id" type="var">t'</span></span> 使
    <span class="inlinecode"><span class="id" type="var">t</span></span> 前进到 <span class="inlinecode"><span class="id" type="var">t'</span></span>，且 <span class="inlinecode"><span class="id" type="var">t'</span></span> 是正规式。

<div class="paragraph"> </div>

    <b>证明草稿</b>：对项进行归纳。有两个情形需要考虑：

<div class="paragraph"> </div>

<ul class="doclist">
<li> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n</span></span> 其中 <span class="inlinecode"><span class="id" type="var">n</span></span> 为数字。这里 <span class="inlinecode"><span class="id" type="var">t</span></span> 无法前进一步，我们有 <span class="inlinecode"><span class="id" type="var">t'</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">t</span></span>。
      我们可以通过自反性证明左手边的项；对于右手边的项，由 <span class="inlinecode"><span class="id" type="var">nf_same_as_value</span></span>
      可得值是正规式，且由 <span class="inlinecode"><span class="id" type="var">v_const</span></span> 可得 <span class="inlinecode"><span class="id" type="var">t</span></span> 是一个值。

<div class="paragraph"> </div>


</li>
<li> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 其中 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 为项。由归纳假设，<span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span>
      分别有正规式 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub>'</span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub>'</span></span>。回忆一下正规式是值（由 <span class="inlinecode"><span class="id" type="var">nf_same_sa_value</span></span>）；
      我们知道 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub>'</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub>'</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n<sub>2</sub></span></span> 其中 <span class="inlinecode"><span class="id" type="var">n<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">n<sub>2</sub></span></span> 为项。
      我们可以使用 <span class="inlinecode"><span class="id" type="var">multi_congr_1</span></span> 和 <span class="inlinecode"><span class="id" type="var">multi_congr_2</span></span> 合并 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 和 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span>
      的 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span> 导出式，以此证明 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 在多步内归约到 <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode">(<span class="id" type="var">n<sub>1</sub></span></span> <span class="inlinecode">+</span> <span class="inlinecode"><span class="id" type="var">n<sub>2</sub></span>)</span>。

<div class="paragraph"> </div>

      显然，我们的选择 <span class="inlinecode"><span class="id" type="var">t'</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode">(<span class="id" type="var">n<sub>1</sub></span></span> <span class="inlinecode">+</span> <span class="inlinecode"><span class="id" type="var">n<sub>2</sub></span>)</span> 是一个值，也是一个正规式。<span class="proofbox">&#9744;</span> 
</li>
</ul>

</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">step_normalizing</span> :<br/>
&nbsp;&nbsp;<span class="id" type="var">normalizing</span> <span class="id" type="var">step</span>.<br/>
<div class="togglescript" id="proofcontrol13" onclick="toggleDisplay('proof13');toggleDisplay('proofcontrol13')"><span class="show"></span></div>
<div class="proofscript" id="proof13" onclick="toggleDisplay('proof13');toggleDisplay('proofcontrol13')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">normalizing</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">induction</span> <span class="id" type="var">t</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;C&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">C</span> <span class="id" type="var">n</span>).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">split</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;l&nbsp;*)</span> <span class="id" type="tactic">apply</span> <span class="id" type="var">multi_refl</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;r&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">(*&nbsp;除了等式，对于当且进当的命题，我们也可以使用&nbsp;<span class="inlinecode"><span class="id" type="tactic">rewrite</span></span>。&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">nf_same_as_value</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">v_const</span>.<br/>
&nbsp;&nbsp;- <span class="comment">(*&nbsp;P&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">IHt1</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">t<sub>1</sub>'</span> [<span class="id" type="var">Hsteps1</span> <span class="id" type="var">Hnormal1</span>]].<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">IHt2</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">t<sub>2</sub>'</span> [<span class="id" type="var">Hsteps2</span> <span class="id" type="var">Hnormal2</span>]].<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">nf_same_as_value</span> <span class="id" type="keyword">in</span> <span class="id" type="var">Hnormal1</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">nf_same_as_value</span> <span class="id" type="keyword">in</span> <span class="id" type="var">Hnormal2</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">Hnormal1</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">H<sub>1</sub></span>].<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">Hnormal2</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">H<sub>2</sub></span>].<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">Hsteps1</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">Hsteps2</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">C</span> (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">split</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;l&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_trans</span> <span class="id" type="keyword">with</span> (<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">t<sub>2</sub></span>).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <span class="id" type="tactic">apply</span> <span class="id" type="var">multistep_congr_1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">Hsteps1</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* <span class="id" type="tactic">apply</span> <span class="id" type="var">multi_trans</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>2</sub></span>)).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <span class="id" type="tactic">apply</span> <span class="id" type="var">multistep_congr_2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">v_const</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">Hsteps2</span>. }<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_R</span>. { <span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>. }<br/>
&nbsp;&nbsp;&nbsp;&nbsp;+ <span class="comment">(*&nbsp;r&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">nf_same_as_value</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">v_const</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
<a name="lab157"></a><h2 class="section">大步语义和小步语义的等价关系</h2>

<div class="paragraph"> </div>

 在使用两种不同的方式（大步和小步式）定义了这个小小语言的操作语义后，你可能会
    好奇这两种定义是否是等价的！他们确实是，尽管需要一点工作来证明它。
    具体细节留做了练习。
<div class="paragraph"> </div>

<a name="lab158"></a><h4 class="section">练习：3 星, standard (eval__multistep)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">eval__multistep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span> <span class="id" type="var">n</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">t</span> ==&gt; <span class="id" type="var">n</span> → <span class="id" type="var">t</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">C</span> <span class="id" type="var">n</span>.<br/>
</div>

<div class="doc">
证明的核心想法以下面的方式展现：

<div class="paragraph"> </div>

<div class="code code-tight">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span>&nbsp;<span class="id" type="var">t<sub>1</sub></span>&nbsp;<span class="id" type="var">t<sub>2</sub></span>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">by</span>&nbsp;<span class="id" type="var">ST_Plus1</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span>&nbsp;<span class="id" type="var">t<sub>1</sub>'</span>&nbsp;<span class="id" type="var">t<sub>2</sub></span>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">by</span>&nbsp;<span class="id" type="var">ST_Plus1</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span>&nbsp;<span class="id" type="var">t<sub>1</sub>''</span>&nbsp;<span class="id" type="var">t<sub>2</sub></span>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">by</span>&nbsp;<span class="id" type="var">ST_Plus1</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span>&nbsp;(<span class="id" type="var">C</span>&nbsp;<span class="id" type="var">n<sub>1</sub></span>)&nbsp;<span class="id" type="var">t<sub>2</sub></span>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">by</span>&nbsp;<span class="id" type="var">ST_Plus2</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span>&nbsp;(<span class="id" type="var">C</span>&nbsp;<span class="id" type="var">n<sub>1</sub></span>)&nbsp;<span class="id" type="var">t<sub>2</sub>'</span>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">by</span>&nbsp;<span class="id" type="var">ST_Plus2</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span>&nbsp;(<span class="id" type="var">C</span>&nbsp;<span class="id" type="var">n<sub>1</sub></span>)&nbsp;<span class="id" type="var">t<sub>2</sub>''</span>&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">by</span>&nbsp;<span class="id" type="var">ST_Plus2</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span>&nbsp;(<span class="id" type="var">C</span>&nbsp;<span class="id" type="var">n<sub>1</sub></span>)&nbsp;(<span class="id" type="var">C</span>&nbsp;<span class="id" type="var">n<sub>2</sub></span>)&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">by</span>&nbsp;<span class="id" type="var">ST_PlusConstConst</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">C</span>&nbsp;(<span class="id" type="var">n<sub>1</sub></span>&nbsp;+&nbsp;<span class="id" type="var">n<sub>2</sub></span>)
<div class="paragraph"> </div>

</div>
    也即，一个形如 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 的项的多步归约关系以如下三步的方式进行：

<div class="paragraph"> </div>

<ul class="doclist">
<li> 首先，使用 <span class="inlinecode"><span class="id" type="var">ST_Plus1</span></span> 数次来归约 <span class="inlinecode"><span class="id" type="var">t<sub>1</sub></span></span> 到正规式，也即必须是一个形如 <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n<sub>1</sub></span></span>
         的项（由 <span class="inlinecode"><span class="id" type="var">nf_same_as_value</span></span>），其中 <span class="inlinecode"><span class="id" type="var">n<sub>1</sub></span></span> 为某个数字。

<div class="paragraph"> </div>


</li>
<li> 接着，使用 <span class="inlinecode"><span class="id" type="var">ST_Plus2</span></span> 数次来归约 <span class="inlinecode"><span class="id" type="var">t<sub>2</sub></span></span> 到正规式，也即必须是一个形如 <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n<sub>2</sub></span></span>
         的项，其中 <span class="inlinecode"><span class="id" type="var">n<sub>2</sub></span></span> 为某个数字。

<div class="paragraph"> </div>


</li>
<li> 最后，使用 <span class="inlinecode"><span class="id" type="var">ST_PlusConstConst</span></span> 一次把 <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode">(<span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n<sub>1</sub></span>)</span> <span class="inlinecode">(<span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">n<sub>2</sub></span>)</span> 归约到
         <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode">(<span class="id" type="var">n<sub>1</sub></span></span> <span class="inlinecode">+</span> <span class="inlinecode"><span class="id" type="var">n<sub>2</sub></span>)</span>。
</li>
</ul>

<div class="paragraph"> </div>

 为了形式化这个直觉的理解，我们需要使用之前的合同（congruence）引理
    （为了帮助后面的证明，你可能需要回顾一下他们），还有一些 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span> 的基础性质：
    自反性，传递性，及其蕴含了 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span></span>。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab159"></a><h4 class="section">练习：3 星, advanced (eval__multistep_inf)</h4>
 请为 <span class="inlinecode"><span class="id" type="var">eval__multi_step</span></span> 写出详细的非形式化证明。

<div class="paragraph"> </div>

<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/>

</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;请勿修改下面这一行：&nbsp;*)</span><br/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">manual_grade_for_eval__multistep_inf</span> : <span class="id" type="var">option</span> (<span class="id" type="var">nat</span>*<span class="id" type="var">string</span>) := <span class="id" type="var">None</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

 对于另一个方向，我们需要一个引理来对单步归约和大步求值建立联系。
<div class="paragraph"> </div>

<a name="lab160"></a><h4 class="section">练习：3 星, standard (step__eval)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">step__eval</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span> <span class="id" type="var">t'</span> <span class="id" type="var">n</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t'</span> ==&gt; <span class="id" type="var">n</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t</span>  ==&gt; <span class="id" type="var">n</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span> <span class="id" type="var">n</span> <span class="id" type="var">Hs</span>. <span class="id" type="tactic">generalize</span> <span class="id" type="tactic">dependent</span> <span class="id" type="var">n</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

 一旦正确地表述了小步归约蕴含了大步求值的事实，它会很容易被证明。

<div class="paragraph"> </div>

    证明是对多步归约序列的归纳，这个序列被假设 <span class="inlinecode"><span class="id" type="var">normal_form_of</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">t'</span></span>
    所隐藏了起来。
<div class="paragraph"> </div>

请确保在开始证明前首先理解了命题。 
<div class="paragraph"> </div>

<a name="lab161"></a><h4 class="section">练习：3 星, standard (multistep__eval)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">multistep__eval</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span> <span class="id" type="var">t'</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">normal_form_of</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span> → <span style='font-size:120%;'>&exist;</span><span class="id" type="var">n</span>, <span class="id" type="var">t'</span> = <span class="id" type="var">C</span> <span class="id" type="var">n</span> ∧ <span class="id" type="var">t</span> ==&gt; <span class="id" type="var">n</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 

<div class="doc">
<a name="lab162"></a><h2 class="section">额外练习</h2>

<div class="paragraph"> </div>

<a name="lab163"></a><h4 class="section">练习：3 星, standard, optional (interp_tm)</h4>
 请回忆一下我们还通过函数 <span class="inlinecode"><span class="id" type="var">evalF</span></span> 定义了对项的大步求值。请证明它等价于其他语义。
    （提示：我刚刚证明了 <span class="inlinecode"><span class="id" type="var">eval</span></span> 和 <span class="inlinecode"><span class="id" type="var">multistep</span></span> 是等价的，因此逻辑上讲你可以任意
    选择证明哪个。尽管有一个要比另一个简单！） 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">evalF_eval</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t</span> <span class="id" type="var">n</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">evalF</span> <span class="id" type="var">t</span> = <span class="id" type="var">n</span> ↔ <span class="id" type="var">t</span> ==&gt; <span class="id" type="var">n</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab164"></a><h4 class="section">练习：4 星, standard (combined_properties)</h4>
 我们分开考虑了算数和条件表达式，这个练习探索了他们之间如何交互。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Module</span> <span class="id" type="var">Combined</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">tm</span> : <span class="id" type="keyword">Type</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">C</span> : <span class="id" type="var">nat</span> → <span class="id" type="var">tm</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">P</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">tru</span> : <span class="id" type="var">tm</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">fls</span> : <span class="id" type="var">tm</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">test</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">value</span> : <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">v_const</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>, <span class="id" type="var">value</span> (<span class="id" type="var">C</span> <span class="id" type="var">n</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">v_tru</span> : <span class="id" type="var">value</span> <span class="id" type="var">tru</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">v_fls</span> : <span class="id" type="var">value</span> <span class="id" type="var">fls</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Reserved Notation</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">step</span> : <span class="id" type="var">tm</span> → <span class="id" type="var">tm</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_PlusConstConst</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">C</span> <span class="id" type="var">n<sub>2</sub></span>) <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">C</span> (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_Plus2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">value</span> <span class="id" type="var">v<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">P</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub>'</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_IfTrue</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">tru</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_IfFalse</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">fls</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ST_If</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">t<sub>1</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">t<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">test</span> <span class="id" type="var">t<sub>1</sub></span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">test</span> <span class="id" type="var">t<sub>1</sub>'</span> <span class="id" type="var">t<sub>2</sub></span> <span class="id" type="var">t<sub>3</sub></span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' " := (<span class="id" type="var">step</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/>
</div>

<div class="doc">
之前，我们分开证明了加法和条件表达式的……

<div class="paragraph"> </div>

<ul class="doclist">
<li> 单步关系是确定的，以及

<div class="paragraph"> </div>


</li>
<li> 一个强可进行引理，陈述了任意项要么是值，要么可以前进一步。

</li>
</ul>
    对于合并起来的语言，请形式化地证明或反驳这两个属性。
    （也即，陈述定理表达性质成立或不成立，并证明它们。） 
</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">End</span> <span class="id" type="var">Combined</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;请勿修改下面这一行：&nbsp;*)</span><br/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">manual_grade_for_combined_properties</span> : <span class="id" type="var">option</span> (<span class="id" type="var">nat</span>*<span class="id" type="var">string</span>) := <span class="id" type="var">None</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 

<div class="doc">
<a name="lab165"></a><h1 class="section">Imp 的小步语义</h1>

<div class="paragraph"> </div>

 现在来看一个更严肃的例子：Imp 的小步操作语义。 
<div class="paragraph"> </div>

 目前为止，给这个小语言添加算数和布尔表达式的小步归约关系是很直接的扩展。
    处于可读性的考虑，我们为他们分别添加记号 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span></span> 和 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span></span>。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">aval</span> : <span class="id" type="var">aexp</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">av_num</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>, <span class="id" type="var">aval</span> (<span class="id" type="var">ANum</span> <span class="id" type="var">n</span>).<br/>
</div>

<div class="doc">
我们在此不会赘述布尔值的定义，因为 <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span></span> 的定义并不需要他们（为什么？），
    尽管当语言规模更大一些时可能会需要到他们（为什么？）。
</div>
<div class="code code-tight">

<span class="id" type="keyword">Reserved Notation</span> " t '/' st '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>a' t' "<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40, <span class="id" type="var">st</span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 39).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">astep</span> : <span class="id" type="var">state</span> → <span class="id" type="var">aexp</span> → <span class="id" type="var">aexp</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Id</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">i</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">AId</span> <span class="id" type="var">i</span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">ANum</span> (<span class="id" type="var">st</span> <span class="id" type="var">i</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Plus1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">APlus</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> (<span class="id" type="var">APlus</span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Plus2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">aval</span> <span class="id" type="var">v<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>2</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">APlus</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> (<span class="id" type="var">APlus</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Plus</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">APlus</span> (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">ANum</span> (<span class="id" type="var">n<sub>1</sub></span> + <span class="id" type="var">n<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Minus1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">AMinus</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> (<span class="id" type="var">AMinus</span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Minus2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">aval</span> <span class="id" type="var">v<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>2</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">AMinus</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> (<span class="id" type="var">AMinus</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Minus</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">AMinus</span> (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>2</sub></span>)) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> (<span class="id" type="var">ANum</span> (<span class="id" type="var">minus</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>))<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Mult1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">AMult</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> (<span class="id" type="var">AMult</span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Mult2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">aval</span> <span class="id" type="var">v<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>2</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">AMult</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> (<span class="id" type="var">AMult</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">AS_Mult</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">AMult</span> (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>2</sub></span>)) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> (<span class="id" type="var">ANum</span> (<span class="id" type="var">mult</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>))<br/>
<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '/' st '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>a' t' " := (<span class="id" type="var">astep</span> <span class="id" type="var">st</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Reserved Notation</span> " t '/' st '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>b' t' "<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40, <span class="id" type="var">st</span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 39).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">bstep</span> : <span class="id" type="var">state</span> → <span class="id" type="var">bexp</span> → <span class="id" type="var">bexp</span> → <span class="id" type="keyword">Prop</span> :=<br/>
| <span class="id" type="var">BS_Eq<sub>1</sub></span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BEq</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> (<span class="id" type="var">BEq</span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>)<br/>
| <span class="id" type="var">BS_Eq<sub>2</sub></span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">aval</span> <span class="id" type="var">v<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>2</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BEq</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> (<span class="id" type="var">BEq</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>)<br/>
| <span class="id" type="var">BS_Eq</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BEq</span> (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>2</sub></span>)) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="keyword">if</span> (<span class="id" type="var">n<sub>1</sub></span> =? <span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="keyword">then</span> <span class="id" type="var">BTrue</span> <span class="id" type="keyword">else</span> <span class="id" type="var">BFalse</span>)<br/>
| <span class="id" type="var">BS_LtEq1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BLe</span> <span class="id" type="var">a<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> (<span class="id" type="var">BLe</span> <span class="id" type="var">a<sub>1</sub>'</span> <span class="id" type="var">a<sub>2</sub></span>)<br/>
| <span class="id" type="var">BS_LtEq2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">aval</span> <span class="id" type="var">v<sub>1</sub></span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a<sub>2</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BLe</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> (<span class="id" type="var">BLe</span> <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="var">a<sub>2</sub>'</span>)<br/>
| <span class="id" type="var">BS_LtEq</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BLe</span> (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>1</sub></span>) (<span class="id" type="var">ANum</span> <span class="id" type="var">n<sub>2</sub></span>)) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="keyword">if</span> (<span class="id" type="var">n<sub>1</sub></span> &lt;=? <span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="keyword">then</span> <span class="id" type="var">BTrue</span> <span class="id" type="keyword">else</span> <span class="id" type="var">BFalse</span>)<br/>
| <span class="id" type="var">BS_NotStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">b<sub>1</sub></span> <span class="id" type="var">b<sub>1</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">b<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">b<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BNot</span> <span class="id" type="var">b<sub>1</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> (<span class="id" type="var">BNot</span> <span class="id" type="var">b<sub>1</sub>'</span>)<br/>
| <span class="id" type="var">BS_NotTrue</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BNot</span> <span class="id" type="var">BTrue</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">BFalse</span><br/>
| <span class="id" type="var">BS_NotFalse</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BNot</span> <span class="id" type="var">BFalse</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">BTrue</span><br/>
| <span class="id" type="var">BS_AndTrueStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">b<sub>2</sub></span> <span class="id" type="var">b<sub>2</sub>'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">b<sub>2</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">b<sub>2</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BAnd</span> <span class="id" type="var">BTrue</span> <span class="id" type="var">b<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> (<span class="id" type="var">BAnd</span> <span class="id" type="var">BTrue</span> <span class="id" type="var">b<sub>2</sub>'</span>)<br/>
| <span class="id" type="var">BS_AndStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">b<sub>1</sub></span> <span class="id" type="var">b<sub>1</sub>'</span> <span class="id" type="var">b<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">b<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">b<sub>1</sub>'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BAnd</span> <span class="id" type="var">b<sub>1</sub></span> <span class="id" type="var">b<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> (<span class="id" type="var">BAnd</span> <span class="id" type="var">b<sub>1</sub>'</span> <span class="id" type="var">b<sub>2</sub></span>)<br/>
| <span class="id" type="var">BS_AndTrueTrue</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BAnd</span> <span class="id" type="var">BTrue</span> <span class="id" type="var">BTrue</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">BTrue</span><br/>
| <span class="id" type="var">BS_AndTrueFalse</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BAnd</span> <span class="id" type="var">BTrue</span> <span class="id" type="var">BFalse</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">BFalse</span><br/>
| <span class="id" type="var">BS_AndFalse</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">b<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">BAnd</span> <span class="id" type="var">BFalse</span> <span class="id" type="var">b<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">BFalse</span><br/>
<br/>
<span class="id" type="keyword">where</span> " t '/' st '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>b' t' " := (<span class="id" type="var">bstep</span> <span class="id" type="var">st</span> <span class="id" type="var">t</span> <span class="id" type="var">t'</span>).<br/>
</div>

<div class="doc">
命令的语义是真正有趣的部分。我们需要两个小技巧来让们工作：

<div class="paragraph"> </div>

<ul class="doclist">
<li> 我们把 <span class="inlinecode"><span class="id" type="var">SKIP</span></span> 当作一个“命令值（command value）”——即，一个已经到达正规式的命令。

<div class="paragraph"> </div>

<ul class="doclist">
<li> 赋值命令归约到 <span class="inlinecode"><span class="id" type="var">SKIP</span></span> （和一个更新状态）。

<div class="paragraph"> </div>


</li>
<li> 顺序命令等待其左侧子命令归约到 <span class="inlinecode"><span class="id" type="var">SKIP</span></span>，然后丢弃它，并继续
              对右侧子命令归约。

<div class="paragraph"> </div>


</li>
</ul>

</li>
<li> 对 <span class="inlinecode"><span class="id" type="var">WHILE</span></span> 命令的归约是把 <span class="inlinecode"><span class="id" type="var">WHILE</span></span> 命令变换为条件语句，其后紧跟同一个
         <span class="inlinecode"><span class="id" type="var">WHILE</span></span> 命令。 
</li>
</ul>

<div class="paragraph"> </div>

 （也有一些其他的方式来达到后一个技巧同样的效果，但当对循环体进行归约时，
    他们都需要将原始的 <span class="inlinecode"><span class="id" type="var">WHILE</span></span> 命令保存在某处。）
</div>
<div class="code code-tight">

<span class="id" type="keyword">Reserved Notation</span> " t '/' st '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' '/' st' "<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40, <span class="id" type="var">st</span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 39, <span class="id" type="var">t'</span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 39).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Open</span> <span class="id" type="keyword">Scope</span> <span class="id" type="var">imp_scope</span>.<br/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">cstep</span> : (<span class="id" type="var">com</span> * <span class="id" type="var">state</span>) → (<span class="id" type="var">com</span> * <span class="id" type="var">state</span>) → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_AssStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">i</span> <span class="id" type="var">a</span> <span class="id" type="var">a'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a</span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">i</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span> <span class="id" type="var">a</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> (<span class="id" type="var">i</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span> <span class="id" type="var">a'</span>) / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_Ass</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">i</span> <span class="id" type="var">n</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">i</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span> (<span class="id" type="var">ANum</span> <span class="id" type="var">n</span>)) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">SKIP</span> / (<span class="id" type="var">i</span> !<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">n</span> ; <span class="id" type="var">st</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_SeqStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>1</sub>'</span> <span class="id" type="var">st'</span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">c<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>1</sub>'</span> / <span class="id" type="var">st'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">c<sub>1</sub></span> ;; <span class="id" type="var">c<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> (<span class="id" type="var">c<sub>1</sub>'</span> ;; <span class="id" type="var">c<sub>2</sub></span>) / <span class="id" type="var">st'</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_SeqFinish</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">SKIP</span> ;; <span class="id" type="var">c<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>2</sub></span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_IfStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">b</span> <span class="id" type="var">b'</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">b</span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">b'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">TEST</span> <span class="id" type="var">b</span>  <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">ELSE</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">FI</span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">TEST</span> <span class="id" type="var">b'</span> <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">ELSE</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">FI</span>) / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_IfTrue</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">TEST</span> <span class="id" type="var">BTrue</span> <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">ELSE</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">FI</span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>1</sub></span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_IfFalse</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">TEST</span> <span class="id" type="var">BFalse</span> <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">ELSE</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">FI</span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>2</sub></span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_While</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">b</span> <span class="id" type="var">c<sub>1</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">WHILE</span> <span class="id" type="var">b</span> <span class="id" type="var">DO</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">END</span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">TEST</span> <span class="id" type="var">b</span> <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span>;; <span class="id" type="var">WHILE</span> <span class="id" type="var">b</span> <span class="id" type="var">DO</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">END</span> <span class="id" type="var">ELSE</span> <span class="id" type="var">SKIP</span> <span class="id" type="var">FI</span>) / <span class="id" type="var">st</span><br/>
<br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '/' st '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' '/' st' " := (<span class="id" type="var">cstep</span> (<span class="id" type="var">t</span>,<span class="id" type="var">st</span>) (<span class="id" type="var">t'</span>,<span class="id" type="var">st'</span>)).<br/><hr class='doublespaceincode'/>
<span class="id" type="var">Close</span> <span class="id" type="keyword">Scope</span> <span class="id" type="var">imp_scope</span>.<br/>
</div>

<div class="doc">
<a name="lab166"></a><h1 class="section">并发 Imp</h1>

<div class="paragraph"> </div>

 最后，为了展示这种定义方式的能力，让我们为 Imp 语言添加一个新的命令，
    使其可以同时运行两个命令，并在两个都停机时停机。为了反映调度的不可预测性，
    子命令可以以任意顺序交错运行，但他们共享了同一个内存，并以读写变量的方式通信。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Module</span> <span class="id" type="var">CImp</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">com</span> : <span class="id" type="keyword">Type</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">CSkip</span> : <span class="id" type="var">com</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CAss</span> : <span class="id" type="var">string</span> → <span class="id" type="var">aexp</span> → <span class="id" type="var">com</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CSeq</span> : <span class="id" type="var">com</span> → <span class="id" type="var">com</span> → <span class="id" type="var">com</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CIf</span> : <span class="id" type="var">bexp</span> → <span class="id" type="var">com</span> → <span class="id" type="var">com</span> → <span class="id" type="var">com</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CWhile</span> : <span class="id" type="var">bexp</span> → <span class="id" type="var">com</span> → <span class="id" type="var">com</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CPar</span> : <span class="id" type="var">com</span> → <span class="id" type="var">com</span> → <span class="id" type="var">com</span>. <span class="comment">(*&nbsp;&lt;---&nbsp;NEW&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Notation</span> "'SKIP'" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">CSkip</span>.<br/>
<span class="id" type="keyword">Notation</span> "x '<span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span>' a" :=<br/>
&nbsp;&nbsp;(<span class="id" type="var">CAss</span> <span class="id" type="var">x</span> <span class="id" type="var">a</span>) (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 60).<br/>
<span class="id" type="keyword">Notation</span> "c<sub>1</sub> ;; c<sub>2</sub>" :=<br/>
&nbsp;&nbsp;(<span class="id" type="var">CSeq</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>) (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 80, <span class="id" type="var">right</span> <span class="id" type="var">associativity</span>).<br/>
<span class="id" type="keyword">Notation</span> "'WHILE' b 'DO' c 'END'" :=<br/>
&nbsp;&nbsp;(<span class="id" type="var">CWhile</span> <span class="id" type="var">b</span> <span class="id" type="var">c</span>) (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 80, <span class="id" type="var">right</span> <span class="id" type="var">associativity</span>).<br/>
<span class="id" type="keyword">Notation</span> "'TEST' b 'THEN' c<sub>1</sub> 'ELSE' c<sub>2</sub> 'FI'" :=<br/>
&nbsp;&nbsp;(<span class="id" type="var">CIf</span> <span class="id" type="var">b</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>) (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 80, <span class="id" type="var">right</span> <span class="id" type="var">associativity</span>).<br/>
<span class="id" type="keyword">Notation</span> "'PAR' c<sub>1</sub> 'WITH' c<sub>2</sub> 'END'" :=<br/>
&nbsp;&nbsp;(<span class="id" type="var">CPar</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>) (<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 80, <span class="id" type="var">right</span> <span class="id" type="var">associativity</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">cstep</span> : (<span class="id" type="var">com</span> * <span class="id" type="var">state</span>)  → (<span class="id" type="var">com</span> * <span class="id" type="var">state</span>) → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">(*&nbsp;Old&nbsp;part&nbsp;*)</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_AssStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">i</span> <span class="id" type="var">a</span> <span class="id" type="var">a'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">a</span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">a</span> <span class="id" type="var">a'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">i</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span> <span class="id" type="var">a</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> (<span class="id" type="var">i</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span> <span class="id" type="var">a'</span>) / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_Ass</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">i</span> <span class="id" type="var">n</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">i</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span> (<span class="id" type="var">ANum</span> <span class="id" type="var">n</span>)) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">SKIP</span> / (<span class="id" type="var">i</span> !<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">n</span> ; <span class="id" type="var">st</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_SeqStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>1</sub>'</span> <span class="id" type="var">st'</span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">c<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>1</sub>'</span> / <span class="id" type="var">st'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">c<sub>1</sub></span> ;; <span class="id" type="var">c<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> (<span class="id" type="var">c<sub>1</sub>'</span> ;; <span class="id" type="var">c<sub>2</sub></span>) / <span class="id" type="var">st'</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_SeqFinish</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">SKIP</span> ;; <span class="id" type="var">c<sub>2</sub></span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>2</sub></span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_IfStep</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">b</span> <span class="id" type="var">b'</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">b</span> /<span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span><span class="id" type="var">b</span> <span class="id" type="var">b'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">TEST</span> <span class="id" type="var">b</span> <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">ELSE</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">FI</span>) / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> (<span class="id" type="var">TEST</span> <span class="id" type="var">b'</span> <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">ELSE</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">FI</span>) / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_IfTrue</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">TEST</span> <span class="id" type="var">BTrue</span> <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">ELSE</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">FI</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>1</sub></span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_IfFalse</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">TEST</span> <span class="id" type="var">BFalse</span> <span class="id" type="var">THEN</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">ELSE</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">FI</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>2</sub></span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_While</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">b</span> <span class="id" type="var">c<sub>1</sub></span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">WHILE</span> <span class="id" type="var">b</span> <span class="id" type="var">DO</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">END</span>) / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> (<span class="id" type="var">TEST</span> <span class="id" type="var">b</span> <span class="id" type="var">THEN</span> (<span class="id" type="var">c<sub>1</sub></span>;; (<span class="id" type="var">WHILE</span> <span class="id" type="var">b</span> <span class="id" type="var">DO</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">END</span>)) <span class="id" type="var">ELSE</span> <span class="id" type="var">SKIP</span> <span class="id" type="var">FI</span>) / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">(*&nbsp;New&nbsp;part:&nbsp;*)</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_Par1</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>1</sub>'</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">st'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">c<sub>1</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>1</sub>'</span> / <span class="id" type="var">st'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">PAR</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">WITH</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">END</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> (<span class="id" type="var">PAR</span> <span class="id" type="var">c<sub>1</sub>'</span> <span class="id" type="var">WITH</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">END</span>) / <span class="id" type="var">st'</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_Par2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">c<sub>2</sub>'</span> <span class="id" type="var">st'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">c<sub>2</sub></span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">c<sub>2</sub>'</span> / <span class="id" type="var">st'</span> →<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">PAR</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">WITH</span> <span class="id" type="var">c<sub>2</sub></span> <span class="id" type="var">END</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> (<span class="id" type="var">PAR</span> <span class="id" type="var">c<sub>1</sub></span> <span class="id" type="var">WITH</span> <span class="id" type="var">c<sub>2</sub>'</span> <span class="id" type="var">END</span>) / <span class="id" type="var">st'</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">CS_ParDone</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span class="id" type="var">PAR</span> <span class="id" type="var">SKIP</span> <span class="id" type="var">WITH</span> <span class="id" type="var">SKIP</span> <span class="id" type="var">END</span>) / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">SKIP</span> / <span class="id" type="var">st</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">where</span> " t '/' st '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>' t' '/' st' " := (<span class="id" type="var">cstep</span> (<span class="id" type="var">t</span>,<span class="id" type="var">st</span>) (<span class="id" type="var">t'</span>,<span class="id" type="var">st'</span>)).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">cmultistep</span> := <span class="id" type="var">multi</span> <span class="id" type="var">cstep</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Notation</span> " t '/' st '<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>' t' '/' st' " :=<br/>
&nbsp;&nbsp;&nbsp;(<span class="id" type="var">multi</span> <span class="id" type="var">cstep</span>  (<span class="id" type="var">t</span>,<span class="id" type="var">st</span>) (<span class="id" type="var">t'</span>,<span class="id" type="var">st'</span>))<br/>
&nbsp;&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 40, <span class="id" type="var">st</span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 39, <span class="id" type="var">t'</span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 39).<br/>
</div>

<div class="doc">
在这个语言的众多特性中，一个有趣的事实是下面的程序在停机时变量 <span class="inlinecode"><span class="id" type="var">X</span></span> 可以是任何值。
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">par_loop</span> : <span class="id" type="var">com</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">PAR</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">Y</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span> 1<br/>
&nbsp;&nbsp;<span class="id" type="var">WITH</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">WHILE</span> <span class="id" type="var">Y</span> = 0 <span class="id" type="var">DO</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">X</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span> <span class="id" type="var">X</span> + 1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">END</span><br/>
&nbsp;&nbsp;<span class="id" type="var">END</span>.<br/>
</div>

<div class="doc">
比如说，它可以当 <span class="inlinecode"><span class="id" type="var">X</span></span> 为 <span class="inlinecode">0</span> 时停机。
</div>
<div class="code code-tight">

<span class="id" type="keyword">Example</span> <span class="id" type="var">par_loop_example_0</span>:<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">st'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">par_loop</span> / <span class="id" type="var">empty_st</span>  <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">SKIP</span> / <span class="id" type="var">st'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;∧ <span class="id" type="var">st'</span> <span class="id" type="var">X</span> = 0.<br/>
<div class="togglescript" id="proofcontrol14" onclick="toggleDisplay('proof14');toggleDisplay('proofcontrol14')"><span class="show"></span></div>
<div class="proofscript" id="proof14" onclick="toggleDisplay('proof14');toggleDisplay('proofcontrol14')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">ex_intro</span>. <span class="id" type="tactic">split</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">par_loop</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par1</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Ass</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_While</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq<sub>1</sub></span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Id</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq</span>. <span class="id" type="tactic">simpl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfFalse</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_ParDone</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_refl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">reflexivity</span>. <span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
它也可以当 <span class="inlinecode"><span class="id" type="var">X</span></span> 为 <span class="inlinecode">2</span> 时停机。
</div>
<div class="code code-tight">

<span class="id" type="keyword">Example</span> <span class="id" type="var">par_loop_example_2</span>:<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">st'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">par_loop</span> / <span class="id" type="var">empty_st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">SKIP</span> / <span class="id" type="var">st'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;∧ <span class="id" type="var">st'</span> <span class="id" type="var">X</span> = 2.<br/>
<div class="togglescript" id="proofcontrol15" onclick="toggleDisplay('proof15');toggleDisplay('proofcontrol15')"><span class="show"></span></div>
<div class="proofscript" id="proof15" onclick="toggleDisplay('proof15');toggleDisplay('proofcontrol15')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">ex_intro</span>. <span class="id" type="tactic">split</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_While</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq<sub>1</sub></span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Id</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq</span>. <span class="id" type="tactic">simpl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfTrue</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_SeqStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">CS_AssStep</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Plus1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Id</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_SeqStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">CS_AssStep</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Plus</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_SeqStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Ass</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_SeqFinish</span>.<br/><hr class='doublespaceincode'/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_While</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq<sub>1</sub></span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Id</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq</span>. <span class="id" type="tactic">simpl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfTrue</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_SeqStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">CS_AssStep</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Plus1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Id</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_SeqStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">CS_AssStep</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Plus</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_SeqStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Ass</span>.<br/><hr class='doublespaceincode'/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Ass</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_SeqFinish</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_While</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq<sub>1</sub></span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Id</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq</span>. <span class="id" type="tactic">simpl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfFalse</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_ParDone</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_refl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">reflexivity</span>. <span class="id" type="keyword">Qed</span>.<br/>
</div>
</div>

<div class="doc">
更一般地…… 
<div class="paragraph"> </div>

<a name="lab167"></a><h4 class="section">练习：3 星, standard, optional (par_body_n__Sn)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">par_body_n__Sn</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span> <span class="id" type="var">st</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">st</span> <span class="id" type="var">X</span> = <span class="id" type="var">n</span> ∧ <span class="id" type="var">st</span> <span class="id" type="var">Y</span> = 0 →<br/>
&nbsp;&nbsp;<span class="id" type="var">par_loop</span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">par_loop</span> / (<span class="id" type="var">X</span> !<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> <span class="id" type="var">S</span> <span class="id" type="var">n</span> ; <span class="id" type="var">st</span>).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab168"></a><h4 class="section">练习：3 星, standard, optional (par_body_n)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">par_body_n</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span> <span class="id" type="var">st</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">st</span> <span class="id" type="var">X</span> = 0 ∧ <span class="id" type="var">st</span> <span class="id" type="var">Y</span> = 0 →<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">st'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">par_loop</span> / <span class="id" type="var">st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>  <span class="id" type="var">par_loop</span> / <span class="id" type="var">st'</span> ∧ <span class="id" type="var">st'</span> <span class="id" type="var">X</span> = <span class="id" type="var">n</span> ∧ <span class="id" type="var">st'</span> <span class="id" type="var">Y</span> = 0.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

 ……上面的循环可以在 <span class="inlinecode"><span class="id" type="var">X</span></span> 为任何值时退出。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">par_loop_any_X</span>:<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">n</span>, <span style='font-size:120%;'>&exist;</span><span class="id" type="var">st'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">par_loop</span> / <span class="id" type="var">empty_st</span> <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>  <span class="id" type="var">SKIP</span> / <span class="id" type="var">st'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;∧ <span class="id" type="var">st'</span> <span class="id" type="var">X</span> = <span class="id" type="var">n</span>.<br/>
<div class="togglescript" id="proofcontrol16" onclick="toggleDisplay('proof16');toggleDisplay('proofcontrol16')"><span class="show"></span></div>
<div class="proofscript" id="proof16" onclick="toggleDisplay('proof16');toggleDisplay('proofcontrol16')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">n</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> (<span class="id" type="var">par_body_n</span> <span class="id" type="var">n</span> <span class="id" type="var">empty_st</span>).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">split</span>; <span class="id" type="tactic">unfold</span> <span class="id" type="var">t_update</span>; <span class="id" type="tactic">reflexivity</span>.<br/><hr class='doublespaceincode'/>
&nbsp;&nbsp;<span class="id" type="tactic">rename</span> <span class="id" type="var">x</span> <span class="id" type="var">into</span> <span class="id" type="var">st</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">H'</span> [<span class="id" type="var">HX</span> <span class="id" type="var">HY</span>]]; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>.<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">Y</span> !<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> 1 ; <span class="id" type="var">st</span>). <span class="id" type="tactic">split</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_trans</span> <span class="id" type="keyword">with</span> (<span class="id" type="var">par_loop</span>,<span class="id" type="var">st</span>). <span class="id" type="tactic">apply</span> <span class="id" type="var">H'</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par1</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Ass</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_While</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq<sub>1</sub></span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">AS_Id</span>. <span class="id" type="tactic">rewrite</span> <span class="id" type="var">t_update_eq</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfStep</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">BS_Eq</span>. <span class="id" type="tactic">simpl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_Par2</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_IfFalse</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">apply</span> <span class="id" type="var">CS_ParDone</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_refl</span>.<br/><hr class='doublespaceincode'/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">t_update_neq</span>. <span class="id" type="tactic">assumption</span>. <span class="id" type="tactic">intro</span> <span class="id" type="var">X</span>; <span class="id" type="tactic">inversion</span> <span class="id" type="var">X</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<br/>
<span class="id" type="keyword">End</span> <span class="id" type="var">CImp</span>.<br/>
</div>

<div class="doc">
<a name="lab169"></a><h1 class="section">小步堆栈机</h1>

<div class="paragraph"> </div>

 最后一个例子来自逻辑基础的 <a href="https://coq-zh.github.io/SF-zh/lf-current/Imp.html"><span class="inlineref">Imp</span></a> 一章，我们给出堆栈机的小步语义。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">stack</span> := <span class="id" type="var">list</span> <span class="id" type="var">nat</span>.<br/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">prog</span>  := <span class="id" type="var">list</span> <span class="id" type="var">sinstr</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Inductive</span> <span class="id" type="var">stack_step</span> : <span class="id" type="var">state</span> → <span class="id" type="var">prog</span> * <span class="id" type="var">stack</span> → <span class="id" type="var">prog</span> * <span class="id" type="var">stack</span> → <span class="id" type="keyword">Prop</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">SS_Push</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">stk</span> <span class="id" type="var">n</span> <span class="id" type="var">p'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">stack_step</span> <span class="id" type="var">st</span> (<span class="id" type="var">SPush</span> <span class="id" type="var">n</span> :: <span class="id" type="var">p'</span>, <span class="id" type="var">stk</span>)      (<span class="id" type="var">p'</span>, <span class="id" type="var">n</span> :: <span class="id" type="var">stk</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">SS_Load</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">stk</span> <span class="id" type="var">i</span> <span class="id" type="var">p'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">stack_step</span> <span class="id" type="var">st</span> (<span class="id" type="var">SLoad</span> <span class="id" type="var">i</span> :: <span class="id" type="var">p'</span>, <span class="id" type="var">stk</span>)      (<span class="id" type="var">p'</span>, <span class="id" type="var">st</span> <span class="id" type="var">i</span> :: <span class="id" type="var">stk</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">SS_Plus</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">stk</span> <span class="id" type="var">n</span> <span class="id" type="var">m</span> <span class="id" type="var">p'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">stack_step</span> <span class="id" type="var">st</span> (<span class="id" type="var">SPlus</span> :: <span class="id" type="var">p'</span>, <span class="id" type="var">n</span>::<span class="id" type="var">m</span>::<span class="id" type="var">stk</span>)  (<span class="id" type="var">p'</span>, (<span class="id" type="var">m</span>+<span class="id" type="var">n</span>)::<span class="id" type="var">stk</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">SS_Minus</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">stk</span> <span class="id" type="var">n</span> <span class="id" type="var">m</span> <span class="id" type="var">p'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">stack_step</span> <span class="id" type="var">st</span> (<span class="id" type="var">SMinus</span> :: <span class="id" type="var">p'</span>, <span class="id" type="var">n</span>::<span class="id" type="var">m</span>::<span class="id" type="var">stk</span>) (<span class="id" type="var">p'</span>, (<span class="id" type="var">m</span>-<span class="id" type="var">n</span>)::<span class="id" type="var">stk</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">SS_Mult</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span> <span class="id" type="var">stk</span> <span class="id" type="var">n</span> <span class="id" type="var">m</span> <span class="id" type="var">p'</span>,<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">stack_step</span> <span class="id" type="var">st</span> (<span class="id" type="var">SMult</span> :: <span class="id" type="var">p'</span>, <span class="id" type="var">n</span>::<span class="id" type="var">m</span>::<span class="id" type="var">stk</span>)  (<span class="id" type="var">p'</span>, (<span class="id" type="var">m</span>*<span class="id" type="var">n</span>)::<span class="id" type="var">stk</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">stack_step_deterministic</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">st</span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">deterministic</span> (<span class="id" type="var">stack_step</span> <span class="id" type="var">st</span>).<br/>
<div class="togglescript" id="proofcontrol17" onclick="toggleDisplay('proof17');toggleDisplay('proofcontrol17')"><span class="show"></span></div>
<div class="proofscript" id="proof17" onclick="toggleDisplay('proof17');toggleDisplay('proofcontrol17')">
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">deterministic</span>. <span class="id" type="tactic">intros</span> <span class="id" type="var">st</span> <span class="id" type="var">x</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">y<sub>2</sub></span> <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="var">H<sub>2</sub></span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">induction</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="tactic">inversion</span> <span class="id" type="var">H<sub>2</sub></span>; <span class="id" type="tactic">reflexivity</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<br/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">stack_multistep</span> <span class="id" type="var">st</span> := <span class="id" type="var">multi</span> (<span class="id" type="var">stack_step</span> <span class="id" type="var">st</span>).<br/>
</div>

<div class="doc">
<a name="lab170"></a><h4 class="section">练习：3 星, advanced (compiler_is_correct)</h4>
 请回忆一下<b>逻辑基础</b> <a href="https://coq-zh.github.io/SF-zh/lf-current/Imp.html"><span class="inlineref">Imp</span></a> 一章中对 <span class="inlinecode"><span class="id" type="var">compile</span></span> 和 <span class="inlinecode"><span class="id" type="var">aexp</span></span> 的定义。
    我们现在想要证明堆栈机上 <span class="inlinecode"><span class="id" type="var">s_compile</span></span> 函数的正确性。

<div class="paragraph"> </div>

    请根据堆栈机的小步语义陈述编译器正确性的定义，并证明它。 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">compiler_is_correct_statement</span> : <span class="id" type="keyword">Prop</span><br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;将本行替换成&nbsp;":=&nbsp;_你的_定义_&nbsp;."&nbsp;*)</span>. <span class="id" type="var">Admitted</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">compiler_is_correct</span> : <span class="id" type="var">compiler_is_correct_statement</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 

<div class="doc">
<a name="lab171"></a><h1 class="section">Aside: A <span class="inlinecode"><span class="id" type="var">normalize</span></span> Tactic</h1>

<div class="paragraph"> </div>

 When experimenting with definitions of programming languages
    in Coq, we often want to see what a particular concrete term steps
    to &mdash; i.e., we want to find proofs for goals of the form <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span></span>
    <span class="inlinecode"><span class="id" type="var">t'</span></span>, where <span class="inlinecode"><span class="id" type="var">t</span></span> is a completely concrete term and <span class="inlinecode"><span class="id" type="var">t'</span></span> is unknown.
    These proofs are quite tedious to do by hand.  Consider, for
    example, reducing an arithmetic expression using the small-step
    relation <span class="inlinecode"><span class="id" type="var">astep</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Example</span> <span class="id" type="var">step_example1</span> :<br/>
&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">C</span> 4)))<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> (<span class="id" type="var">C</span> 10).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_step</span> <span class="id" type="keyword">with</span> (<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">C</span> 7)).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ST_Plus2</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">v_const</span>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_step</span> <span class="id" type="keyword">with</span> (<span class="id" type="var">C</span> 10).<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ST_PlusConstConst</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_refl</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<div class="doc">
The proof repeatedly applies <span class="inlinecode"><span class="id" type="var">multi_step</span></span> until the term reaches a
    normal form.  Fortunately The sub-proofs for the intermediate
    steps are simple enough that <span class="inlinecode"><span class="id" type="tactic">auto</span></span>, with appropriate hints, can
    solve them. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Hint</span> <span class="id" type="var">Constructors</span> <span class="id" type="var">step</span> <span class="id" type="var">value</span>.<br/>
<span class="id" type="keyword">Example</span> <span class="id" type="var">step_example1'</span> :<br/>
&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">C</span> 4)))<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> (<span class="id" type="var">C</span> 10).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="tactic">simpl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="tactic">simpl</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_refl</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<div class="doc">
The following custom <span class="inlinecode"><span class="id" type="keyword">Tactic</span></span> <span class="inlinecode"><span class="id" type="keyword">Notation</span></span> definition captures this
    pattern.  In addition, before each step, we print out the current
    goal, so that we can follow how the term is being reduced. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "print_goal" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; ?<span class="id" type="var">x</span> ⇒ <span class="id" type="var">idtac</span> <span class="id" type="var">x</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "normalize" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> (<span class="id" type="var">print_goal</span>; <span class="id" type="tactic">eapply</span> <span class="id" type="var">multi_step</span> ;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ (<span class="id" type="tactic">eauto</span> 10; <span class="id" type="tactic">fail</span>) | (<span class="id" type="var">instantiate</span>; <span class="id" type="tactic">simpl</span>)]);<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">multi_refl</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Example</span> <span class="id" type="var">step_example1''</span> :<br/>
&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">C</span> 4)))<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> (<span class="id" type="var">C</span> 10).<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="var">normalize</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;The&nbsp;<span class="inlinecode"><span class="id" type="var">print_goal</span></span>&nbsp;in&nbsp;the&nbsp;<span class="inlinecode"><span class="id" type="var">normalize</span></span>&nbsp;tactic&nbsp;shows<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;trace&nbsp;of&nbsp;how&nbsp;the&nbsp;expression&nbsp;reduced...<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(P&nbsp;(C&nbsp;3)&nbsp;(P&nbsp;(C&nbsp;3)&nbsp;(C&nbsp;4))&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>&nbsp;C&nbsp;10)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(P&nbsp;(C&nbsp;3)&nbsp;(C&nbsp;7)&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>&nbsp;C&nbsp;10)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(C&nbsp;10&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>&nbsp;C&nbsp;10)<br/>
&nbsp;&nbsp;*)</span><br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<div class="doc">
The <span class="inlinecode"><span class="id" type="var">normalize</span></span> tactic also provides a simple way to calculate the
    normal form of a term, by starting with a goal with an existentially
    bound variable. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Example</span> <span class="id" type="var">step_example1'''</span> : <span style='font-size:120%;'>&exist;</span><span class="id" type="var">e'</span>,<br/>
&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">C</span> 4)))<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">e'</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">ex_intro</span>. <span class="id" type="var">normalize</span>.<br/>
<span class="comment">(*&nbsp;This&nbsp;time,&nbsp;the&nbsp;trace&nbsp;is:<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(P&nbsp;(C&nbsp;3)&nbsp;(P&nbsp;(C&nbsp;3)&nbsp;(C&nbsp;4))&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>&nbsp;?e')<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(P&nbsp;(C&nbsp;3)&nbsp;(C&nbsp;7)&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>&nbsp;?e')<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(C&nbsp;10&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span>&nbsp;?e')<br/>
&nbsp;&nbsp;&nbsp;where&nbsp;?e'&nbsp;is&nbsp;the&nbsp;variable&nbsp;``guessed''&nbsp;by&nbsp;eapply.&nbsp;*)</span><br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<div class="doc">
<a name="lab172"></a><h4 class="section">练习：1 星, standard (normalize_ex)</h4>

</div>
<div class="code code-space">
<span class="id" type="keyword">Theorem</span> <span class="id" type="var">normalize_ex</span> : <span style='font-size:120%;'>&exist;</span><span class="id" type="var">e'</span>,<br/>
&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 2) (<span class="id" type="var">C</span> 1)))<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">e'</span> ∧ <span class="id" type="var">value</span> <span class="id" type="var">e'</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="doc less-space">
<div class="paragraph"> </div>

<a name="lab173"></a><h4 class="section">练习：1 星, standard, optional (normalize_ex')</h4>
 For comparison, prove it using <span class="inlinecode"><span class="id" type="tactic">apply</span></span> instead of <span class="inlinecode"><span class="id" type="tactic">eapply</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Theorem</span> <span class="id" type="var">normalize_ex'</span> : <span style='font-size:120%;'>&exist;</span><span class="id" type="var">e'</span>,<br/>
&nbsp;&nbsp;(<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 3) (<span class="id" type="var">P</span> (<span class="id" type="var">C</span> 2) (<span class="id" type="var">C</span> 1)))<br/>
&nbsp;&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:6%;'><span style='letter-spacing:-.2em;'>-</span><span style='letter-spacing:-.2em;'>-</span></span><span style='letter-spacing:-.2em;'>&gt;</span><span style='vertical-align:15%;'>*</span></span></span> <span class="id" type="var">e'</span> ∧ <span class="id" type="var">value</span> <span class="id" type="var">e'</span>.<br/>
<span class="id" type="keyword">Proof</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;请在此处解答&nbsp;*)</span> <span class="id" type="var">Admitted</span>.<br/>
</div>

<span class="proofbox">&#9744;</span> 
<div class="code code-tight">

<span class="comment">(*&nbsp;Mon&nbsp;Oct&nbsp;28&nbsp;08:15:18&nbsp;UTC&nbsp;2019&nbsp;*)</span><br/>
</div>
</div>



</div>

</body>
</html>